Ответ 1
У меня была такая же проблема сегодня.
Легче, если вы просто выполните:
composer require firebase/php-jwt:4.0
Подтверждение Google в Интернете привело меня к сумасшедшему...
Я создаю простое веб-приложение, и я пытаюсь интегрировать функцию входа Google на веб-сайт (https://developers.google.com/identity/sign-in/web/).
JavaScript, похоже, прошел достаточно хорошо, и следующим шагом было проверить id_token
, который я получал на моем бэкэнд-сервере (опять же, против рекомендации Google: https://developers.google.com/identity/sign-in/web/backend-auth).
Это веб-приложение на основе PHP, и я успешно установил библиотеку API клиента Google с помощью композитора: 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...')
Я также использовал значение id_token
в конечной точке "tokeninfo" Google (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>
... и мой 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);
}
?>
Большое вам спасибо за то, что нашли время, чтобы прочитать это и за любую помощь! Он очень благодарен!
У меня была такая же проблема сегодня.
Легче, если вы просто выполните:
composer require firebase/php-jwt:4.0
Это проблема с php-jwt. Последняя версия не работает с клиентом Google Api.
Попробуйте использовать версию php-jwt версии 4.
Я положил "firebase/php-jwt": "< 5.0" в мой файл composer.json.
Работал как шарм!
У меня проблемы с проверкой подлинности входа в систему Google вчера, используя как google/apiclient 2.2.0, так и 2.1.3.
tl; dr это, скорее всего, сбои на стороне Google или некоторые неясные ограничения, о которых я не знаю (ничего в консоли разработчика об этом не было).
Во-первых, "idToken", который Google предоставлял мне на стороне клиента, не был действительным JWT: openssl_verify() отклонял его в Firebase\JWT\JWT, бросая Firebase\JWT\SignatureInvalidException. Я последовал вашим советам, установил google/apiclient 2.1.3, и это исключение больше не выбрасывалось, но полученная полезная нагрузка была нулевой (поэтому idToken все еще недействителен).
Несколько часов спустя, я испытал периодические результаты с apiclient 2.3.0: иногда токен был недействителен проверкой подписи (и выбрасывал исключение подписи), а иногда токен был криптографически действителен, но возвращаемая полезная нагрузка была нулевой. Время от времени маркер был действительным (!).
В конце концов, аутентификационный процесс бэкэнд выполнялся каждый раз.
По мере того как я начал испытывать эти проблемы, я попытался исправить это, создав новые ключи OAuth2, вернусь к предыдущим версиям моей кодовой базы (как на стороне сервера, так и на стороне клиента), которые, как я знал, работали, удалили все данные браузера и попытались чтобы получить токен на Кордове с помощью входа для Android. Ничего не получилось. Также нет сообщений в Консоли разработчика, никаких видимых ограничений, нет электронной почты безопасности.
Если это не ошибка, а функция, обработка ошибок довольно жесткая:)
К счастью, вы можете проверить id_token
без библиотеки google, как описано здесь 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 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.1 google/apiclient, поэтому убедитесь, что вы используете эту версию или более позднюю версию, если кто-то еще сталкивается с этим проблема.