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:composer require google/apiclient
成功安装了Google Client API库,但在将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...')
我还在Google的“tokeninfo”端点(https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=ABC123)上使用了id_token
值,id_token
完美地验证了,所以我确定它不是{{1}这是错的。它也通过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>
非常感谢您花时间阅读本文,并提供任何帮助!非常感谢!
答案 0 :(得分:11)
我今天遇到了同样的问题。
如果您执行以下操作更容易:
composer require firebase/php-jwt:4.0
答案 1 :(得分:3)
幸运的是,您可以在没有Google图书馆的情况下验证id_token
,如https://developers.google.com/identity/sign-in/web/backend-auth#calling-the-tokeninfo-endpoint
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());
}
}
}
如果您没有例外,那么您的令牌有效
答案 2 :(得分:2)
这是php-jwt的一个问题。最新版本不适用于Google Api客户端。
尝试使用php-jwt版本4。
我在我的composer.json文件中放了“firebase / php-jwt”:“&lt; 5.0”。
充当魅力!
答案 3 :(得分:1)
我昨天使用google / apiclient 2.2.0和2.1.3进行了Google登录后端身份验证。
tl;博士很可能是谷歌方面的故障或者我不知道的一些模糊限制(开发者控制台中没有任何关于此的内容)。
首先,&#34; idToken&#34;谷歌给我的客户端不是有效的JWT:openssl_verify()在Firebase \ JWT \ JWT中拒绝它,抛出Firebase \ JWT \ SignatureInvalidException。我按照你的建议,安装了google / apiclient 2.1.3,这个异常不再被抛出,但结果有效负载为空(所以idToken仍然无效)。
几个小时之后,我遇到了apiclient 2.3.0的间歇性结果:有时签名验证无效(并抛出签名异常),有时令牌加密有效但返回的有效负载为空。偶尔,令牌有效(!)。
最后,后端身份验证过程每次都成功。
当我开始遇到这些问题时,我尝试修复它生成新的OAuth2密钥,恢复到我知道正在运行的代码库(服务器端和客户端)的先前版本,删除所有浏览器数据并尝试使用Sign In for Android在Cordova上获取令牌。没有任何效果。此外,开发人员控制台中没有消息,没有可见限制,没有安全电子邮件。
如果它不是错误而是功能,则错误处理非常苛刻:)
答案 4 :(得分:1)
答案 5 :(得分:0)
如果您不使用Firebase(取自https://github.com/googleapis/google-api-php-client)
rm -r vendor/google/apiclient-services
将此添加到composer.json
"scripts": {
"post-update-cmd": "Google\\Task\\Composer::cleanup"
},
"extra": {
"google/apiclient-services": [
"Drive" ,
"... any other services here ...",
]
}
最后
composer install
这将解决错误消息,并具有大大减少已安装软件包的额外好处。如上所述,GAPI至少有200种API服务