網路資源:
- https://firebase.google.com/docs/auth/admin/verify-id-tokens
- https://jwt.io/
- https://github.com/lcobucci/jwt/tree/3.2 (因應 PHP 5.x 使用 3.2.2版)
- https://github.com/kreait/firebase-php
用法:
$ mkdir jwt-3.2.2 ; cd jwt-3.2.2 ; composer require lcobucci/jwt
$ vim test.php
<?php
require 'vendor/autoload.php';
$token_string = 'XXXXXXXXXXX';
$signer = new Lcobucci\JWT\Signer\Rsa\Sha256();
$keychain = new Lcobucci\JWT\Signer\Keychain;
$parser = new Lcobucci\JWT\Parser;
try {
 $token = $parser->parse($token_string);
} catch( Exception $e ) {
 echo "decode failed\n";
 exit;
}
// check key field
foreach (array( 'iat', 'exp', 'aud', 'iss', 'user_id' ) as $field) {
 if (!$token->hasClaim($field)) {
  echo "no $field\n";
  exit;
 }
}
if ($token->isExpired()) {
 echo "exp expired\n";
 exit;
}
if (!$token->hasHeader('kid')) {
 echo "no kid\n";
 exit;
}
$kid = $token->getHeader('kid');
$keys = json_decode(file_get_contents('https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com'), true);
if (!isset($keys[$kid])) {
 echo "kid not found\n";
 exit;
}
try {
 if( $token->verify($signer, $keychain->getPublicKey($keys[$kid])) )
  echo "PASS\n";
} catch (Exception $e) {
 echo "Failed";
}
$user_id = $token->getClaim('user_id');
連續動作(PHP Codeigniter Usage):
$ cat Jwt_library.php
<?php
require_once 'jwt-3.2.2/vendor/autoload.php';
class Jwt_library {
 public function __construct() {
  $this->ci = &get_instance();
  $this->parser = new Lcobucci\JWT\Parser;
  $this->keychain = new Lcobucci\JWT\Signer\Keychain;
  $this->signer = new Lcobucci\JWT\Signer\Rsa\Sha256;
 }
 public function verify_firebase_token(&$error, $user_token, $project_id, $service_public_keys = array()) {
  $user_id = NULL;
  $error = NULL;
  $token = false;
  try {
   $token = $this->parser->parse($user_token);
  } catch (Exception $e) {
   $error= 'decode failed';
   return NULL;
  }
  // check filed name
  foreach (array( 'iat', 'exp', 'aud', 'iss', 'user_id' ) as $field) {
   if (!$token->hasClaim($field)) {
    $error = "no $field";
    return NULL;
   }
  }
  if ($token->isExpired()) {
   $error = 'exp expired';
   return NULL;
  }
  //if ($token->getClaim('iat') > time() )
  // return 'token has been issued in the future';
  if ($token->getClaim('aud') != $project_id ) {
   $error = 'aud error';
   return NULL;
  }
  $user_id = $token->getClaim('user_id');
  $kid = false;
  try{
   $kid = $token->getHeader('kid');
  } catch (Exception $e) {
   $error = 'no kid';
   return NULL;
  }
  if (!isset($service_public_keys[$kid])) {
   $error = 'kid not found: '.$kid;
   return NULL;
  }
  try {
   if ($token->verify($this->signer, $this->keychain->getPublicKey($service_public_keys[$kid])))
    return $user_id;
  } catch (Exception $e) {
   $error = 'verify failed';
  }
  return NULL;
 }
}
$ cat php_ci_controller.php
<?php
$output = array( 'status' => false );
$authorization_info = $this->input->get_request_header('Authorization', True);
if (empty($authorization_info) || strstr($authorization_info, 'Bearer ') == false) {
        $output['error'] = -1;
        $output['message'] = 'no Authorization';
        $this->_json_output($output);
        return;
}
$firebase_user_token = trim(substr($authorization_info, strlen('Bearer ')));
$this->load->library('jwt_library');
$keys = @json_decode(@file_get_contents('https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com'), true);
$firebase_user_id = $this->jwt_library->verify_firebase_token($verify_error, $firebase_user_token, 'YourFirebaseProjectId', $keys);
if (empty($firebase_user_id)) {
 $output['error'] = 1;
 $output['message'] = 'verify: '.$verify_error;
 $this->_json_output($output);
 return;
}
 




