Я запрашиваю доступ к данным пользователя из приложения IOS, используя этот код из модуля GoogleSignIn.
[GIDSignIn sharedInstance].uiDelegate = self;
[[GIDSignIn sharedInstance] setScopes:@[ ... ];
[[GIDSignIn sharedInstance] signInSilently];
Затем я получаю accessToken и refreshToken в appDelegate и отправляю их на сервер, на котором запущен PHP и использует эту клиентскую библиотеку Google (https://github.com/googleapis/google-api-php-client) ... в течение первого часа все работает нормально, и токен доступа действителен и разрешает мне доступ во все области. Затем через час токен доступа истекает, и я пытаюсь обновить его с помощью этого кода.
$client = new Google_Client();
$client->setApplicationName(<app name>);
$client->setDeveloperKey(<google_oauth_developer_key>);
$client->setClientSecret(<google_oauth_client_secret>);
$client->setClientId(<google_oauth_client_id>);
$client->refreshToken("1/12ju3ZZim-r6co195lIVNNvzBq9x5G64GJCWkYsOQ18");
и приведенная выше функция "refreshToken" возвращает эту ошибку.
=> [
"error" => "unauthorized_client",
"error_description" => "Unauthorized",
]
Стоит отметить, что app name, google_oauth_developer_key, google_oauth_client_secret и google_oauth_client_id не изменились. Это те же самые, которые раньше работали для получения контактов пользователя, событий календаря и т. Д., Когда токен доступа еще не истек.
Что могло быть причиной этой ошибки?
Ответ 1 · рейтинг 1 · DaImTo
В какой-то момент вам действительно нужно использовать токен обновления.
if ($client->isAccessTokenExpired()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
$client->getAccessToken();
Код скопирован из моего Пример Oauth2Authentication.php
Примечание
Также помните, что токены обновления основаны на пользователе / клиенте. Таким образом, если токен был сгенерирован одним клиентом, другой клиент, вероятно, не сможет его использовать. Я буду очень удивлен, если вы сможете использовать токен обновления, созданный в коде iOS, в приложении php. Типы клиентов разные.
Ответ 2 · Yaseen Aniss
Итак, я понял, что сделал не так. Изначально я выполнил эти инструкции https://developers.google.com/identity/sign-in/ios/sign-in, которые предполагают, что вам нужен только онлайн-доступ, но мне действительно нужен автономный доступ к областям, поэтому я выполнил следующие инструкции https://developers.google.com/identity/sign-in/ios/offline-access, и теперь он работает. Поэтому вместо того, чтобы приложение IOS отправляло токен доступа и токен обновления отдельно, как это
- (void)signIn:(GIDSignIn *)signIn didSignInForUser:(GIDGoogleUser *)user
withError:(NSError *)error {
if (!error) {
NSString *accessToken = user.authentication.accessToken;
NSString *refreshToken = user.authentication.refreshToken;
Я просто прошу это послать serverAuthCode вот так
- (void)signIn:(GIDSignIn *)signIn didSignInForUser:(GIDGoogleUser *)user
withError:(NSError *)error {
if (!error) {
NSString *serverAuthCode = user.serverAuthCode;
а затем на сервере я запускаю этот код, чтобы получить токен доступа
$access_token = $client->authenticate($google_server_auth_code);
$client->setAccessToken($access_token);
а затем, когда токен доступа истекает, я запускаю его, чтобы обновить его
$access_token = $client->refreshToken($client->getRefreshToken());
$client->setAccessToken($access_token);