Я следую документам по ссылке ниже:
https://developers.google.com/+/mobile/android/sign-in#enable_server-side_api_access_for_your_app
В частности, та часть, в которой говорится:
Если вам не требуется автономный доступ, вы можете получить токен доступа и отправить его на свой сервер через безопасное соединение. Вы можете получить токен доступа напрямую с помощью GoogleAuthUtil.getToken(), указав области без идентификатора клиента OAuth 2.0 вашего сервера. Например:
Я получаю токен доступа следующим образом:
accessToken = GoogleAuthUtil.getToken(
AuthenticatorActivity.this,
Plus.AccountApi.getAccountName(Common.mGoogleApiClient),
"oauth2:https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/plus.login email"
);
После того, как я получаю токен доступа, я отправляю его на веб-сервер, на веб-сервере я вижу, что это действительный токен доступа, вызывая
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token='.$_POST['google_access_token']
Приведенный выше запрос возвращает идентификатор клиента приложений для Android, а также правильно возвращает электронную почту пользователей.
Проблема в том, что когда я пытаюсь запустить $client->authenticate($_POST['google_access_token']); Я получаю исключение с сообщением: «invalid_grant: неправильный тип токена».
Чтобы предотвратить кэширование getToken, я всегда аннулирую токен в приложении для Android:
if (accessToken != null && !accessToken.isEmpty()) { GoogleAuthUtil.invalidateToken(AuthenticatorActivity.this, accessToken); }
Вот php-код:
if (!isset($_POST['google_access_token'])) {
throw new Exception('missing google_access_token');
}
$client = new \Google_Client();
$client->setApplicationName("GiverHub");
$client->setClientId($this->config->item('google_client_id'));
$client->setClientSecret($this->config->item('google_client_secret'));
$client->setDeveloperKey($this->config->item('google_developer_key'));
$client->setRedirectUri($this->config->item('google_redirect_uri'));
$client->setScopes([
'https://www.googleapis.com/auth/plus.login',
'https://www.googleapis.com/auth/plus.me',
'email',
]);
try {
$client->authenticate($_POST['google_access_token']); // if i remove this the rest of the code below works! ...
$reqUrl = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token='.$_POST['google_access_token'];
$req = new \Google_Http_Request($reqUrl);
$io = $client->getIo();
$response = $io->executeRequest($req);
$response = $response[0];
$response = json_decode($response, true);
if ($response === null) {
throw new Exception('Failed to check token. response null');
}
if ($response['issued_to'] !== '466530377541-s7cfm34jpf818gbr0547pndpq9songkg.apps.googleusercontent.com') {
throw new Exception('Invalid access token. issued to wrong client id: '. print_r($response, true));
}
if (!isset($response['user_id'])) {
throw new Exception('Missing user_id');
}
if (!isset($response['email'])) {
throw new Exception('Missing email');
}
/** @var \Entity\User $user */
$user = Common::create_member_google([
'id' => $response['user_id'],
'email' => $response['email'],
'given_name' => '',
'family_name' => '',
]);
$user->login($this->session);
if ($user instanceof \Entity\User) {
echo json_encode( [ 'success' => true, 'user' => $user ] );
} else {
echo json_encode( [ 'success' => false, 'msg' => $user ] );
}
} catch(Exception $e) {
echo json_encode(['success' => false, 'msg' => $e->getMessage()]);
}
Приведенный выше код работает, если я удаляю $client->authenticate(); строка... Проблема в том, что я не могу получить заданное_имя/фамильное_имя и т.д.. только адрес электронной почты/google_user_id из tokeninfo...
Любые мысли о том, почему ключ работает для tokeninfo, но не для аутентификации?
Я пробовал много разных вариантов областей... как на стороне сервера, так и на стороне андроида...