android — аутентифицируйте токен доступа, предоставленный GoogleAuthUtil.getToken после отправки его на веб-сервер php

Я следую за документами по ссылке ниже:

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 (); строка … Проблема в том, что я не могу получить имя_файла / фамилию и т. д. .. только email / google_user_id из tokeninfo …

Любые мысли о том, почему ключ работает для tokeninfo, но не для аутентификации?

Я пробовал много разных вариантов областей видимости .. как на стороне сервера, так и на стороне Android ..

1

Решение

$client->authenticate() Метод не совсем делает то, что вы пытаетесь сделать. Он берет одноразовый код из предыдущей транзакции OAuth и обменивает его на токен доступа. В вашем случае — вы говорите, что у вас уже есть токен доступа.

Вы должны быть в состоянии позвонить $client->setAccessToken() вместо этого установить токен, чтобы он мог выглядеть примерно так

$client->setAccessToken($_POST['google_access_token']);
0

Другие решения

Это решение я придумал после того, как пользователь 158443 предложил использовать $ client-> setAccessToken ();

// first json_encode the access token before sending it to $client->setAccessToken();
$json_encoded_access_token = json_encode([
'access_token' => $_POST['google_access_token'],
'created' => time(),  // make up values for these.. otherwise the client thinks the token has expired..
'expires_in' => time()+60 // made up a value in the future...
]);

// and then set it
$client->setAccessToken($json_encoded_access_token);

// and then get userinfo or whatever you want from google api !! :)
$oauth2 = new \Google_Service_Oauth2($client);
$user_info = $oauth2->userinfo->get();

НОТА: вероятно, не очень разумно «эмулировать» expires_in и созданный, который я только что сделал, если вы работаете … Вы должны сначала вызвать tokeninfo и получить оттуда время истечения …

НОТА: Я до сих пор не знаю, как получить токен обновления для этого … но мне не нужен один для моего случая использования ..

0

По вопросам рекламы [email protected]