Firebase 身份验证与来自 php

时间:2021-02-01 23:54:32

标签: php firebase google-cloud-platform jwt php-jwt

我有一个 PHP 应用程序,我正在尝试生成一个令牌来对用户进行身份验证,以便他们可以从浏览器访问 Firebase。

我在 Firebase 控制台中从服务帐户生成了一个私钥,并使用了 firebase/php-jwt 库。尝试使用来自 javascript 的 signInWithCustomToken 方法访问时,我总是收到错误>

<块引用>

自定义令牌格式不正确。请参阅文档

我生成令牌的代码是:

use Firebase\JWT\JWT;

require_once("php-jwt-master/src/JWT.php");

$service_account_email = "firebase-adminsdk-ierut@......iam.gserviceaccount.com"; // Dots are app name

$key = "-----BEGIN PRIVATE KEY-----\n..........\n-----END PRIVATE KEY-----\n"; // Dots are private key from the downloaded file

$time = time();

$token = array( 'iat' => $time,
                'exp' => $time + 3000,
                'uid' => '1',
                'aud' => 'https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit',
                'iss' => $service_account_email,
                'sub' => $service_account_email
               );
               

$jwt = JWT::encode($token, $key, 'HS256');

javascript 代码是:

function login(){

  var token = document.getElementById("token").value;

  firebase.auth().signInWithCustomToken(token)      
    .then((user) => {           
      console.log("Autenticado");         
    })      
    .catch((error) => {         
      var errorCode = error.code;
      var errorMessage = error.message;
      
      console.log(errorCode + " - " + errorMessage);          
    });
}

我已经用 jwt.io 工具检查过 jwt,它似乎是正确的。

我不确定密钥格式,我试过在文件中将标题和“\ n”放在一行中,也没有“\ n”,并在带有“的多行变量中使用返回” <<<”。

我也尝试过使用带有或不带有参数“HS256”的编码函数。但我总是得到同样的错误。

提前感谢您的回复。

2 个答案:

答案 0 :(得分:1)

我能理解为什么这可能会让人有点困惑,因为一些文档和代码相互矛盾。甚至 firebase/php-jwt/src/JWT.php 文件也提到 HS256supported algorithm

class JWT
    . . .
    public static $supported_algs = array(
        'ES256' => array('openssl', 'SHA256'),
        'HS256' => array('hash_hmac', 'SHA256'),
        'HS384' => array('hash_hmac', 'SHA384'),
        'HS512' => array('hash_hmac', 'SHA512'),
        'RS256' => array('openssl', 'SHA256'),
        'RS384' => array('openssl', 'SHA384'),
        'RS512' => array('openssl', 'SHA512'),
    );

但是,根据 Google OAuth 2.0 文档,它明确提到:

<块引用>

Google OAuth 2.0 授权服务器支持的唯一签名算法是使用 SHA-256 散列算法的 RSA。这在 JWT 标头的 alg 字段中表示为 RS256

我按照以下文档在我的 Linux 机器上对此进行了测试:

我安装了所有要求:

$ sudo apt update -y && sudo apt upgrade -y
$ sudo apt install php libapache2-mod-php
$ sudo systemctl start apache2
$ sudo apt install php-cli unzip
$ curl -sS https://getcomposer.org/installer -o composer-setup.php
$ HASH=`curl -sS https://composer.github.io/installer.sig`
$ php -r "if (hash_file('SHA384', 'composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
$ sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer
$ composer require firebase/php-jwt

我创建了一个 jwt-auth.php 文件:

<?php
// Requires: composer require firebase/php-jwt
use Firebase\JWT\JWT;

require __DIR__ . '/vendor/autoload.php';

// Get your service account's email address and private key from the JSON key file
$service_account_email = "firebase-adminsdk-<REDACTED>@<REDACTED>.iam.gserviceaccount.com";

$privateKey = <<<EOD
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC8kGa . . . <REDACTED> . . .
B2zNzvrlgRmgBrklMTrMYgm1NPcW+bRLGcwgW2PTvNM=
-----END RSA PRIVATE KEY-----
EOD;

$publicKey = <<<EOD
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3D . . . <REDACTED> . . .
ehde/zUxo6UvS7UrBQIDAQAB
-----END PUBLIC KEY-----
EOD;

$now_seconds = time();

$payload = array(
    "iss" => $service_account_email,
    "sub" => $service_account_email,
    "aud" => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
    "iat" => $now_seconds,
    "exp" => $now_seconds+(60*60),  // Maximum expiration time is one hour
    "uid" => "1"
);

$jwt = JWT::encode($payload, $privateKey, 'RS256');
echo "Encode:\n" . print_r($jwt, true) . "\n";

$decoded = JWT::decode($jwt, $publicKey, array('RS256'));

/*
 NOTE: This will now be an object instead of an associative array. To get
 an associative array, you will need to cast it as such:
*/

$decoded_array = (array) $decoded;
echo "Decode:\n" . print_r($decoded_array, true) . "\n";

?>

跑:

$ php jwt-auth.php

而且我能够进行身份验证:

Encode:
eyJ0eXAiOiJKV1QiL . . . <REDACTED> . . .ZnverW8YFTaC_ZVFnI
Decode:
Array
(
    [iss] => firebase-adminsdk-<REDACTED>@<REDACTED>.iam.gserviceaccount.com
    [sub] => firebase-adminsdk-<REDACTED>@<REDACTED>.iam.gserviceaccount.com
    [aud] => https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit
    [iat] => 1618406214
    [exp] => 1618409814
    [uid] => 1
)

答案 1 :(得分:0)

已解决,将算法名称从 HS256 更改为 RS256!。谢谢。