谷歌网络登录让我非常疯狂......
我正在构建一个简单的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 客户端 API 库,但是当将我的id_token
值发布到我的 PHP 后端系统时,我不断收到以下错误:
FirebaseJWTSignatureInvalidException
File: .vendorfirebasephp-jwtsrcJWT.php:112
Message: Signature verification failed
Stack trace:
#0 .vendorgoogleapiclientsrcGoogleAccessTokenVerify.php(103): FirebaseJWTJWT::decode('eyJhbGciOiJSUzI...', '-----BEGIN PUBL...', Array)
#1 .vendorgoogleapiclientsrcGoogleClient.php(712): Google_AccessToken_Verify->verifyIdToken('eyJhbGciOiJSUzI...', '10...')
我还在Google的"tokeninfo"端点(https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=ABC123(上使用了id_token
值,并且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>
。和我的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);
}
?>
非常感谢您抽出宝贵时间阅读本文,并提供任何帮助!非常感谢!
我今天遇到了同样的问题。
如果你只是执行,更容易:
作曲家需要 Firebase/PHP-JWT:4.0
幸运的是,您可以在没有谷歌图库的情况下验证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 GuzzleHttpClient())->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 GuzzleHttpPsr7Response $resp */
$resp = $e->getResponse();
$error = json_decode($resp->getBody()->getContents(), true)['error_description'];
throw new Exception($error, $resp->getStatusCode());
}
}
}
如果您没有例外,那么您的令牌是有效的
这是php-jwt的问题。最新版本不适用于谷歌 API 客户端。
尝试使用 php-jwt 版本 4。
我把"firebase/php-jwt":"<5.0"放在我的composer.json文件中。
作为魅力工作!
此问题已在 google/apiclient 的 v2.2.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 仍然无效(。
几个小时后,我在使用 apiclient 2.3.0 时遇到了间歇性的结果:有时令牌通过签名验证(并引发签名异常(失效,有时令牌在加密上有效,但返回的有效负载为空。偶尔,令牌是有效的(!
最后,后端身份验证过程每次都成功。
当我开始遇到这些问题时,我试图修复它生成新的 OAuth2 密钥,恢复到我知道正在工作的我的代码库(服务器端和客户端(的先前版本,删除所有浏览器数据并尝试通过 Android 登录在 Cordova 上获取令牌。什么都没用。开发人员控制台中也没有消息,没有可见的限制,没有安全电子邮件。
如果它不是一个错误而是一个功能,那么错误处理是非常苛刻的:)
如果您没有使用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 服务