使用php设置firebase v3自定义身份验证

时间:2016-06-14 01:08:49

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

我尝试使用google新的firebase sdk设置自定义身份验证,遵循以下准则:https://firebase.google.com/docs/auth/server#use_a_jwt_library
在samble代码中它说:

  

从JSON密钥文件中获取您的服务帐户的电子邮件地址和私钥

不幸的是我不知道从哪里获取这个json文件。如果我转到我的firebase控制台(https://console.firebase.google.com/),我设法下载一个json文件,但它不包含任何电子邮件地址和私钥。

我设法在google云平台控制台(http://console.cloud.google.com)中找到一个包含电子邮件地址和私钥的json文件,直接进入" API管理器>凭证"菜单。令人惊讶的是我的firebase应用程序在那里展示我将电子邮件和密钥复制并粘贴到示例代码中,然后我收到了此错误:

  

警告:openssl_sign():提供的密钥参数无法强制转换为第183行/volume1/web/yeti/vendor/firebase/php-jwt/src/JWT.php中的私钥致命错误:未捕获异常&# 39; DomainException'消息' OpenSSL无法签署数据'在/volume1/web/yeti/vendor/firebase/php-jwt/src/JWT.php:185堆栈追踪:#0 /volume1/web/yeti/vendor/firebase/php-jwt/src/JWT.php(154 ):Firebase \ JWT \ JWT :: sign(' eyJ0eXAiOiJKV1Q ......',NULL,' RS256')#1 /volume1/web/yeti/jwt.php(21) :Firebase \ JWT \ JWT :: encode(Array,NULL,' RS256')#2 /volume1/web/yeti/jwt.php(24):create_custom_token(' 1234', false)在第185行的/volume1/web/yeti/vendor/firebase/php-jwt/src/JWT.php中抛出#3 {main}

有人知道我做错了吗?

由于

5 个答案:

答案 0 :(得分:7)

您找到了解决方案吗?仍然遇到同样的问题!适用于HS256,不适用于RS256。这是google cloud的一种限制吗?

非常感谢你! @dbburgess

问题:使用了错误的密钥和电子邮件。这些应在与Firebase项目对应的Google Cloud凭据部分中生成。

解决方案:

  • 转到“console.cloud.google.com”。
  • 选择相关的Firebase项目。
  • 然后'API Manager' - > '证书'。
  • '创建凭据' - > '服务帐户密钥' - >选择JSON。
  • 创建的文件将包含所需的'private_key'和& 'client_email'。

填写值:

$ service_account_email =“autogeneratedemail@developer.gserviceaccount.com”;   $ private_key =“----- BEGIN PRIVATE KEY ----- \ nSoneVeryVeryLongKey = \ n ----- END PRIVATE KEY ----- \ n”;   $ uid ='UserToUseInFirebaseRules';   $ is_premium_account = $ uid;

您不需要在“create_custom_token”功能中更改任何内容,也可以根据需要更改到期日期/时间。

然后调用函数:

create_custom_token($uid, $is_premium_account);

答案 1 :(得分:4)

发现自己出了什么问题! 来自文档的示例php代码是错误的。而不是

return JWT::encode($payload, $private_key, "RS256");

使用

return JWT::encode($payload, $private_key, "HS256");

编辑:
实际上,它只是来自google firebase doc的示例php代码,完全是错误的。它将一个空键传递给php-jwt。看起来他们今天更新了它并且工作正常:))

答案 2 :(得分:3)

这就是我正在做的事情,它运作正常。您在claims数组中提供的内容是安全规则中auth上显示的内容。电子邮件和密钥来自您create a service account时获得的json文件(请参阅:开始之前部分)。

$userId = '1234';
$email = 'sample@email.com';
$key = 'giant_key_goes_here';

$payload = [
    'iss' => $email,
    'sub' => $email,
    'aud' => 'https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit',
    'iat' => time(),
    'exp' => time() + 60 * 60,
    'uid' => $userId,
    'claims' => [
        'uid' => $userId,
    ],
];

$token = JWT::encode($payload, $key, 'RS256');

值得注意的是,键上的格式有点棘手......你的键看起来像这样(只是一个示例键):

-----BEGIN PRIVATE KEY-----
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
-----END PRIVATE KEY-----

您可能需要做一些花哨的格式化,这基本上就是我所做的:

$key = "-----BEGIN PRIVATE KEY-----\nMIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp\nwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5\n1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh\n3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2\npIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX\nGukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il\nAkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF\nL0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k\nX6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl\nU9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ\n37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=\n-----END PRIVATE KEY-----\n";

请注意,换行符会变为\n,并且会全部按到一行。有各种方法可以实现它,但是......基于你得到的错误,这样的事情可能就是问题所在。

答案 3 :(得分:0)

我遇到了同样的问题。阅读@ Jean-Philippe答案后,我能够使用HS256而不是RS256生成令牌。但这即使在更改凭据后也始终会导致无效令牌。

使用jwt.io对其进行调试,一切都是正确的,但仍然从firebase.auth().signInWithCustomToken(token).catch(function (error) {}获得无效令牌。

在github中搜索后,我发现了this issue。因此,我在$private中使用双引号而不是单引号,并且它与RS256一起使用。

require_once('../vendor/autoload.php');
use \Firebase\JWT\JWT;

$service_account_email = env('ACCOUNT_EMAIL');
$private_key = env('ACCOUNT_SECRET');

class generateToken
{
    public static function generateNewToken($mysqli, $userID, $email)
    {
        global $service_account_email, $private_key;

        $name = '';
        $lastname = '';
        $hostOption = '';
        $now_seconds = time();

        $selectUserData = "SELECT username, lastname, hostOption FROM signup WHERE id = ? ";
        $stmt = $mysqli->prepare($selectUserData);
        $stmt->bind_param('i', $userID);
        $stmt->execute();
        $stmt->store_result();
        $stmt->bind_result($name, $lastname, $hostOption);
        $stmt->fetch();

        $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" => strval($userID),
            "claims" => array(
                "username" => $name,
                "lastname" => $lastname,
                "email" => $email,
                "hostOption" => $hostOption,
            )
        );

        return JWT::encode($payload, $private_key, 'RS256');
    }
}

env.php:

$vars = [
    'ACCOUNT_EMAIL' => "admin@myproject.iam.gserviceaccount.com",
    'ACCOUNT_SECRET' => "-----BEGIN PRIVATE KEY-----\nVERYLONGKEY=\n-----END PRIVATE KEY-----\n"
];

foreach($vars as $key => $value){
    putenv("$key=$value");
}
lindelius commented on 7 Aug 2018 • 
The reason is because the key contains new-line characters (\n) which are incorrectly handled when used within single-quotes, i.e. they are treated as the characters "\n" rather than actual new lines.

答案 4 :(得分:-1)

而不是

function ajaxcall()
{
console.log('i am called');
        var values = {
            'name': document.getElementById('name').value,
            'message': document.getElementById('message').value
        };

             $.ajax({
                type: "POST",
                url: "chat.php",
                data: values,
                success: function(data){
                    $("#chat").html(data);
                }
            });

}

$(document).ready(function(){
var id = setInterval(function() {
   ajaxcall();
}, 1000);
    });

使用

$key = 'giant_key_goes_here';
token = JWT::encode($payload, $key, 'RS256');