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

问题描述 投票:11回答:5

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

我正在构建一个简单的Web应用程序,我正在尝试将Google登录功能集成到网站(qazxsw poi)中。

JavaScript看起来相当不错,下一步是验证我使用后端服务器接收的https://developers.google.com/identity/sign-in/web/(再次,针对谷歌的推荐:id_token)。

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

id_token

我还在Google的“tokeninfo”端点(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...') )上使用了id_token值,并且https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=ABC123完美地验证了,所以我确定id_token值不是错误的。它也通过POST变量完美地传递给PHP脚本,所以我有点亏。

这是我的代码:

使用Javascript:

id_token

...和我的PHP捕获POST:

<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>

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

javascript php google-api-php-client google-signin
5个回答
11
投票

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

如果你只是执行:

composer require firebase/php-jwt:4.0

3
投票

幸运的是,您可以在没有谷歌库的情况下验证<?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); } ?> ,如此处所述id_token

https://developers.google.com/identity/sign-in/web/backend-auth#calling-the-tokeninfo-endpoint

如果您没有例外,则您的令牌有效


2
投票

这是php-jwt的一个问题。最新版本不适用于Google Api客户端。

尝试使用php-jwt版本4。

我把“firebase / php-jwt”:“<5.0​​”放在我的composer.json文件中。

作为一个魅力!


1
投票

我昨天使用google / apiclient 2.2.0和2.1.3进行了Google登录后端身份验证。

tl;博士很可能是谷歌方面的故障或一些我不知道的模糊限制(在开发者控制台中没有任何关于这一点)。

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

几个小时之后,我在经历了2.3.0时出现间歇性结果:有时令牌被签名验证无效(并抛出签名异常),有时候令牌在加密方面有效,但返回的有效负载为空。偶尔,令牌有效(!)。

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

当我开始遇到这些问题时,我试图修复它生成新的OAuth2密钥,恢复到我知道正在工作的代码库(服务器端和客户端)的先前版本,删除所有浏览器数据并尝试获取适用于Android的登录Cordova上的令牌。没有任何效果。 Developer Console中也没有消息,没有可见限制,没有安全电子邮件。

如果它不是一个bug而是一个功能,那么错误处理非常苛刻:)


1
投票

这已在google / apiclient的 if (isset($data['id_token'])) { $id_token = trim($data['id_token']); try { $res = (new \GuzzleHttp\Client())->request('GET', 'https://www.googleapis.com/oauth2/v3/tokeninfo', [ 'query' => ['id_token' => $id_token], ]); $payload = json_decode($res->getBody()->getContents(), true); //you still need to check that the aud claim contains one of your app's client IDs if ($payload['aud'] != "client-id-is-here") { throw new \Exception("App Isn't valid", 422); } } catch (RequestException $e) { //IF token isn't valid you will be here if ($e->hasResponse()) { /** @var \GuzzleHttp\Psr7\Response $resp */ $resp = $e->getResponse(); $error = json_decode($resp->getBody()->getContents(), true)['error_description']; throw new \Exception($error, $resp->getStatusCode()); } } } 中修复,因此如果有其他人遇到此问题,请确保您运行此版本或更高版本。

相关讨论v2.2.1here

© www.soinside.com 2019 - 2024. All rights reserved.