Google登录网站,导致JWT PHP库"签名验证失败"

Chr*_*pen 11 javascript php google-api-php-client google-signin

Google网站登录让我感到非常疯狂......

我正在构建一个简单的Web应用程序,我正在尝试将Google的登录功能集成到网站中(https://developers.google.com/identity/sign-in/web/).

JavaScript看起来相当不错,下一步是验证id_token我使用后端服务器收到的信息(再次,根据Google的建议:https://developers.google.com/identity/sign-in/web/backend- auth).

这是一个基于PHP的Web应用程序,我已经使用composer:成功安装了Google Client API库composer require google/apiclient,但是当我将我的id_token值发布到我的PHP后端系统时,我一直收到以下错误:

Firebase\JWT\SignatureInvalidException
File: .\vendor\firebase\php-jwt\src\JWT.php:112 
Message: Signature verification failed

Stack trace:
#0 .\vendor\google\apiclient\src\Google\AccessToken\Verify.php(103): Firebase\JWT\JWT::decode('eyJhbGciOiJSUzI...', '-----BEGIN PUBL...', Array)
#1 .\vendor\google\apiclient\src\Google\Client.php(712): Google_AccessToken_Verify->verifyIdToken('eyJhbGciOiJSUzI...', '10...')
Run Code Online (Sandbox Code Playgroud)

我还使用了id_tokenGoogle的"tokeninfo"端点(https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=ABC123)上的值,并且id_token验证完美,所以我确定它的id_token值不是错误.它也通过POST变量完美地传递给PHP脚本,所以我有点亏.

这是我的代码:

使用Javascript:

<script src="https://apis.google.com/js/platform.js?onload=googleAppStart" async defer></script>
<script>
    var googleAppStart  = function(){gapi.load('auth2', initGoogleSignIn);};
    var auth            = false;
    function initGoogleSignIn(){
        auth = gapi.auth2.init({
            client_id   : 'client-id-is-here',
            scope       : 'profile'
        });

        auth.attachClickHandler(document.getElementById('my-button'));
        auth.isSignedIn.listen(googleSignInChanged);
        auth.currentUser.listen(googleCurrentUserChanged);

        if (auth.isSignedIn.get() == true)
            auth.signIn();
    }

    function googleSignInChanged(signed_in){}
    function googleCurrentUserChanged(user){
        var auth_response   = user.getAuthResponse();
        var id_token        = auth_response.id_token;
        if (id_token != undefined){
            var url     = '/verify-google-signin';
            var params  = {id_token: id_token};
            jQuery.post(url, params, function(data){}, 'json');
        }
    }
</script>
Run Code Online (Sandbox Code Playgroud)

...和我的PHP捕获POST:

<?php

    require_once '/vendor/autoload.php';

    $credentials = array("client_id" => "client-id-is-here");
    $client = new \Google_Client($credentials);

    $data = $_POST;
    if (isset($data['id_token'])) {

        $id_token = trim($data['id_token']);

        // Exception generated here...
        $payload = $client->verifyIdToken($id_token);
    }

?>
Run Code Online (Sandbox Code Playgroud)

非常感谢您花时间阅读本文,并提供任何帮助!非常感谢!

小智 11

我今天遇到了同样的问题.

如果你只是执行:

composer require firebase/php-jwt:4.0


小智 1

我昨天使用 google/apiclient 2.2.0 和 2.1.3 时遇到了 Google 登录后端身份验证问题。

tl;dr 这很可能是 Google 方面的故障或一些我不知道的模糊限制(开发者控制台中没有任何相关内容)。

首先,Google 给我客户端的“idToken”不是有效的 JWT:openssl_verify() 在 Firebase\JWT\JWT 中拒绝它,抛出 Firebase\JWT\SignatureInvalidException。我听从了你的建议,安装了 google/apiclient 2.1.3,并且不再抛出此异常,但生成的有效负载为空(因此 idToken 仍然无效)。

几个小时后,我在 apiclient 2.3.0 中遇到了间歇性的结果:有时令牌因签名验证而失效(并引发签名异常),有时令牌在加密上是有效的,但返回的有效负载为空。偶尔,令牌是有效的(!)。

最后,后端验证过程每次都成功。

当我开始遇到这些问题时,我尝试修复它,生成新的 OAuth2 密钥,恢复到我知道正在工作的以前版本的代码库(服务器端和客户端),删除所有浏览器数据并尝试获取Cordova 上的令牌与 Android 登录。什么都没起作用。开发人员控制台中也没有消息,没有可见的限制,没有安全电子邮件。

如果这不是一个错误而是一个功能,那么错误处理是相当严厉的:)