How to verify firebase ID token with PHP(JWT)?

前端 未结 4 1390
盖世英雄少女心
盖世英雄少女心 2020-12-14 17:32

I have a shared hosting plan which has only PHP(no Java, no node.js). I need to send firebase ID token from my android app and verify it by PHP-JWT.

I am following t

4条回答
  •  遥遥无期
    2020-12-14 18:10

    If anyone is still interested, @CFP Support's answer is quite good for servers using PHP 5.6, but it does have some bugs while trying to cache the expiration time of the current saved public keys. I've taken that code, and made the necessary corrections:

    Requirements in composer.json

    {
        "require" : {
            "firebase/php-jwt": "5.2.0"
        }
    }
    

    Usage

    );
    ?>
    

    Functions

    exp > time();
                    # ist must be in the past
                    $iat = $decoded->iat < time();
                    # aud must be firebase project ID
                    $aud = $decoded->aud == $jwt['project_id'];
                    # iss must be https://securetoken.google.com/
                    $iss = $decoded->iss == 'https://securetoken.google.com/'.$jwt['project_id'];
                    # sub must be non-empty and is the UID of the user or device
                    $sub = $decoded->sub;
                    # check all items
                    if($exp && $iat && $aud && $iss && !empty($sub)) {
                        # confirmed firebase user
                        $return['user']['uid'] = $sub;
                        // $return['user']['email'] = $decoded->email;
                        // $return['user']['name'] = $decoded->name;
                        // $return['user']['picture'] = $decoded->picture;
                        // $return['all'] = $decoded;
                    } else {
                    }
                }
            } catch (\UnexpectedValueException $unexpectedValueException) {
                $return['error'] = $unexpectedValueException->getMessage();
                //$unexpectedValueException->getMessage()
            }
        }
        return $return;
    }
    
    # checks whether new keys should be downloaded
    # retrieves them if needed
    function jwt_check_keys() {
        global $jwt;
        if(file_exists($jwt['cache'])) {
            $fp_cache = fopen($jwt['cache'], 'r+');
            if(flock($fp_cache, LOCK_SH)) {
                $cachetime = fread($fp_cache, filesize($jwt['cache']));
                if($cachetime > time()) {
                    # still valid - do nothing
                    flock($fp_cache, LOCK_UN);
                } elseif(flock($fp_cache, LOCK_EX)) {
                    # expired - refresh public keys
                    jwt_refresh_keys();
                    flock($fp_cache, LOCK_UN);
                } else {
                    throw new \RuntimeException('Cannot refresh keys: file lock upgrade error.');
                }
            } else {
                throw new \RuntimeException('Cannot refresh keys: file lock error.');
            }
            fclose($fp_cache);
        } else {
            # refresh public keys
            jwt_refresh_keys();
        }
    }
    
    # downloads the public keys and writes them in a file
    # sets the new cache revalidation time
    function jwt_refresh_keys() {
        global $jwt;
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, 'https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HEADER, 1);
        $data = curl_exec($ch);
        $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
        $headers = trim(substr($data, 0, $header_size));
        $raw_keys = trim(substr($data, $header_size));
        if(preg_match('/max-age=(\d+)/', $headers, $age_matches) === 1) {
            # update new cache expiration timestamp
            $fp_cache = fopen($jwt['cache'], 'w');
            $age = $age_matches[1];
            fwrite($fp_cache, ''.(time() + $age));
            fflush($fp_cache);
    
            # update public keys
            $fp_keys = fopen($jwt['keys'], 'w');
            if(flock($fp_keys, LOCK_EX)) {
                fwrite($fp_keys, $raw_keys);
                fflush($fp_keys);
                flock($fp_keys, LOCK_UN);
            }
            fclose($fp_keys);
        }
    }
    
    # retrieves the downloaded keys
    # this should be called anytime you need the keys (i.e. for decoding / verification)
    function jwt_get_keys() {
        global $jwt;
        $fp = fopen($jwt['keys'], 'r');
        $keys = null;
        if(flock($fp, LOCK_SH)) {
            $keys = fread($fp, filesize($jwt['keys']));
            flock($fp, LOCK_UN);
        }
        fclose($fp);
        return $keys;
    }
    ?>
    

提交回复
热议问题