Как проверить токен доступа API аутентификации Google?

134

Как я могу проверить токен доступа Google для аутентификации?

Мне нужно как-то запросить Google и спросить: действителен ли [данный токен доступа] для [example@example.com] учетной записи Google?

Короткая версия :
Понятно, как токен доступа, предоставляемый через Аутентификацию Google Api :: OAuth для веб-приложений, можно использовать для запроса данных из ряда служб Google. Не ясно, как проверить, является ли данный токен доступа действительным для данной учетной записи Google. Я хотел бы знать, как.

Длинная версия :
я разрабатываю API, который использует аутентификацию на основе токенов. Токен будет возвращен после предоставления действительного имени пользователя + пароля или при предоставлении стороннего токена от любой из N проверяемых служб.

Одним из сторонних сервисов будет Google, позволяющий пользователю проходить аутентификацию на моем сервисе, используя свою учетную запись Google. Позже это будет расширено, чтобы включить учетные записи Yahoo, доверенных поставщиков OpenID и так далее.

Схематический пример доступа на основе Google:

альтернативный текст http://webignition.net/images/figures/auth_figure002.png

Сущность «API» находится под моим полным контролем. Объект «открытый интерфейс» - это любое веб-приложение или приложение для настольного компьютера. Некоторые публичные интерфейсы находятся под моим контролем, другие не будут, а другие, о которых я, возможно, даже не узнаю.

Поэтому я не могу доверять токену, предоставленному API на шаге 3. Он будет предоставлен вместе с соответствующим адресом электронной почты аккаунта Google.

Мне нужно как-то запросить Google и спросить: действителен ли этот токен доступа для example@example.com ?

В этом случае example@example.com - это уникальный идентификатор учетной записи Google - адрес электронной почты, который кто-то использует для входа в свою учетную запись Google. Это нельзя считать адресом Gmail - кто-то может иметь учетную запись Google, не имея учетной записи Gmail.

В документации Google четко указано, как с помощью маркера доступа можно получать данные из ряда служб Google. Кажется, ничто не говорит о том, как вы можете проверить, является ли данный токен доступа действительным с самого начала.

Обновление Маркер действителен для N сервисов Google. Я не могу использовать токен для службы Google в качестве средства проверки, так как не буду знать, какое подмножество всех служб Google на самом деле использует данный пользователь.

Кроме того, я никогда не буду использовать токен аутентификации Google для доступа к каким-либо службам Google, просто как средство подтверждения того, что предполагаемый пользователь Google на самом деле является тем, кем они себя называют. Если есть другой способ сделать это, я с удовольствием попробую.

Джон Крам
источник
О какой конкретной службе аутентификации идет речь (OAuth, AuthSub, Installed Apps, ...)? Пожалуйста, предоставьте более подробную ссылку.
Мартин против Лёвиса
@Martin v. Löwis: служба «OAuth-аутентификация для веб-приложений» - я обновил начало вопроса, чтобы отразить это. Спасибо за указание на это!
Джон Крам
интересная статья о проверке ключа Google может дать больше информации о groups.google.com/group/Google-Maps-API/msg/f9e3c5ad3cbda4d7
dotjoe

Ответы:

138

Для проверки пользователя просто опубликуйте маркер доступа как accessToken, опубликуйте его и получите ответ

https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=accessToken

Вы также можете попробовать в адресной строке в браузерах, используйте httppost и ответ в Java также

ответ будет как

{
     "issued_to": "xxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com",
     "audience": "xxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com",
     "user_id": "xxxxxxxxxxxxxxxxxxxxxxx",
     "scope": "https://www.googleapis.com/auth/userinfo.profile https://gdata.youtube.com",
     "expires_in": 3340,
     "access_type": "offline"
    }

Область действия - это предоставленное разрешение accessToken. Вы можете проверить идентификаторы области в этой ссылке

Обновление: новый пост API, как показано ниже

https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123

Ответ будет как

 {
 // These six fields are included in all Google ID Tokens.
 "iss": "https://accounts.google.com",
 "sub": "110169484474386276334",
 "azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "iat": "1433978353",
 "exp": "1433981953",

 // These seven fields are only included when the user has granted the "profile" and
 // "email" OAuth scopes to the application.
 "email": "testuser@gmail.com",
 "email_verified": "true",
 "name" : "Test User",
 "picture": "https://lh4.googleusercontent.com/-kYgzyAWpZzJ/ABCDEFGHI/AAAJKLMNOP/tIXL9Ir44LE/s99-c/photo.jpg",
 "given_name": "Test",
 "family_name": "User",
 "locale": "en"
}

Для получения дополнительной информации, https://developers.google.com/identity/sign-in/android/backend-auth

Винодж Джон Хосан
источник
11
Существует более новая версия Google oauth2 - v3. Смотрите пример здесь: developers.google.com/identity/sign-in/android/backend-auth
AlikElzin-kilaka
30

вы можете проверить токен доступа аутентификации Google, используя эту конечную точку:

https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=<access_token>

Это проверенная конечная точка Google V3 OAuth AccessToken, вы можете сослаться на документ Google ниже: (во OAUTH 2.0 ENDPOINTSвкладке)

https://developers.google.com/identity/protocols/OAuth2UserAgent#validate-access-token

Ник Цай
источник
Для документации Backend - источник документации здесь
eton_ceb
26

Хорошо, большинство ответов верны, но не совсем правильны. Идея JWT заключается в том, что вы можете проверить токен без необходимости каждый раз связываться с эмитентом. Вы должны проверить идентификатор и проверить подпись токена с помощью известного открытого ключа сертификата, который Google использовал для подписи токена.

Смотрите следующий пост, почему и как это сделать.

http://ncona.com/2015/02/consuming-a-google-id-token-from-a-server/

Ремко
источник
3
Больше голосов, пожалуйста! The idea of JWT is that you can validate the token without the need to contact the issuer everytime.
Мориц Шмитц против
да! Если вы просто позвоните в Google, чтобы
узнать
Вы не можете сделать это с помощью токенов доступа Google, потому что они не являются JWT. Проверьте stackoverflow.com/questions/48623656/…
DanielJaramillo
18
function authenticate_google_OAuthtoken($user_id)
{
    $access_token   = google_get_user_token($user_id); // get existing token from DB
    $redirecturl    = $Google_Permissions->redirecturl;
    $client_id      = $Google_Permissions->client_id;
    $client_secret  = $Google_Permissions->client_secret;
    $redirect_uri   = $Google_Permissions->redirect_uri;
    $max_results    = $Google_Permissions->max_results;

    $url = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token='.$access_token;
    $response_contacts  =  curl_get_responce_contents($url);
    $response   =   (json_decode($response_contacts));

    if(isset($response->issued_to))
    {
        return true;
    }
    else if(isset($response->error))
    {
        return false;
    }
}
Ahmed
источник
2
Этот ответ почти все еще действителен. Issued_to, похоже, больше не устанавливается. developers.google.com/accounts/docs/…
frostymarvelous
6

Ответ о потоке кода Google oauth в дополнение к access_tokenвозвратам id_token, содержащим полезную для проверки информацию в зашифрованном виде.

Одна вещь, которая делает токены ID полезными, это тот факт, что вы можете передавать их по разным компонентам вашего приложения. Эти компоненты могут использовать маркер идентификатора в качестве упрощенного механизма аутентификации для аутентификации приложения и пользователя. Но прежде чем вы сможете использовать информацию в идентификационном токене или использовать ее как подтверждение того, что пользователь прошел аутентификацию, вы должны проверить ее.

Проверка идентификатора токена требует нескольких шагов:

  • Убедитесь, что идентификационный токен - это JWT, который правильно подписан соответствующим открытым ключом Google.
  • Убедитесь, что значение aud в токене идентификатора равно идентификатору клиента вашего приложения.
  • Убедитесь, что значение iss в токене идентификатора равно account.google.com или https://accounts.google.com .
  • Убедитесь, что время истечения (exp) идентификатора токена не прошло.
  • Если вы передали в запросе параметр hd, убедитесь, что у идентификатора токена есть утверждение hd, соответствующее вашему размещенному домену Служб Google.

https://developers.google.com/identity/protocols/OpenIDConnect#validatinganidtoken link содержит примеры кода для проверки идентификационных токенов.

См. Также /security/37818/why-use-openid-connect-instead-of-plain-oauth .

Vadzim
источник
1

Мне нужно как-то запросить Google и спросить: действителен ли этот токен доступа для example@example.com?

Нет. Все, что вам нужно, это запросить стандартный вход в систему с помощью федеративного входа для пользователей аккаунта Google из вашего домена API. И только после этого вы можете сравнить «постоянный идентификатор пользователя» с идентификатором из «открытого интерфейса».

Значение области используется на странице входа в систему Google Federated Login для идентификации запрашивающего сайта для пользователя. Он также используется для определения значения постоянного идентификатора пользователя, возвращаемого Google.

Таким образом, вы должны быть из того же домена, что и «публичный интерфейс».

И не забывайте, что пользователь должен быть уверен, что вашему API можно доверять;) Поэтому Google спросит пользователя, позволяет ли он проверить его личность.

Malx
источник
1

Вот пример использования Guzzle :

/**
 * @param string $accessToken JSON-encoded access token as returned by \Google_Client->getAccessToken() or raw access token
 * @return array|false False if token is invalid or array in the form
 * 
 * array (
 *   'issued_to' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com',
 *   'audience' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com',
 *   'scope' => 'https://www.googleapis.com/auth/calendar',
 *   'expires_in' => 3350,
 *   'access_type' => 'offline',
 * )
 */
public static function tokenInfo($accessToken) {
    if(!strlen($accessToken)) {
        return false;
    }

    if($accessToken[0] === '{') {
        $accessToken = json_decode($accessToken)->access_token;
    }

    $guzzle = new \GuzzleHttp\Client();

    try {
        $resp = $guzzle->get('https://www.googleapis.com/oauth2/v1/tokeninfo', [
            'query' => ['access_token' => $accessToken],
        ]);
    } catch(ClientException $ex) {
        return false;
    }

    return $resp->json();
}
mpen
источник
0

Попробуйте сделать запрос с аутентификацией OAuth, используя свой токен, на https://www.google.com/accounts/AuthSubTokenInfo . Это задокументировано только для работы с AuthSub, но работает и с OAuth. Он не сообщит вам, для какого пользователя предназначен токен, но сообщит, для каких служб он действителен, и запрос не будет выполнен, если токен недействителен или был отозван.

Джонатан
источник
0

Произвольный токен доступа OAuth нельзя использовать для аутентификации, поскольку значение токена выходит за рамки спецификации OAuth Core. Он может быть предназначен для одноразового использования или с ограниченным сроком действия, или он может предоставлять доступ, который пользователь не хочет предоставлять. Он также непрозрачен, и получатель OAuth, возможно, никогда не видел идентификатора пользователя какого-либо типа.

Поставщик услуг OAuth и один или несколько потребителей могут легко использовать OAuth для предоставления проверяемого токена аутентификации, и есть предложения и идеи, чтобы сделать это там, но произвольный поставщик услуг, говорящий только на OAuth Core, не может предоставить это без других совместных действий. рукоположение с потребителем. Специфичный для Google метод REST AuthSubTokenInfo вместе с идентификатором пользователя близок, но также не подходит, так как он может сделать токен недействительным или срок действия токена может истечь.

Если ваш Google ID является идентификатором OpenId, а ваш «общедоступный интерфейс» является либо веб-приложением, либо может вызывать браузер пользователя, вам, вероятно, следует использовать Google OpenID OP.

OpenID состоит из простой отправки пользователя в OP и получения обратно подписанного утверждения. Взаимодействие осуществляется исключительно на благо РП. Не существует долгоживущего токена или другого пользовательского дескриптора, который можно было бы использовать для указания того, что RP успешно аутентифицировал пользователя с помощью OP.

Один из способов проверить предыдущую аутентификацию по идентификатору OpenID - просто снова выполнить аутентификацию, предполагая, что используется тот же пользовательский агент. OP должен иметь возможность возвращать положительное утверждение без взаимодействия с пользователем (например, путем проверки файла cookie или сертификата клиента). OP может потребовать другого взаимодействия с пользователем и, вероятно, будет, если запрос аутентификации поступает из другого домена (мой OP дает мне возможность повторно аутентифицировать этот конкретный RP без взаимодействия в будущем). А в случае Google пользовательский интерфейс, через который пользователь прошел для получения токена OAuth, может не использовать тот же идентификатор сеанса, поэтому пользователю придется повторно аутентифицироваться. Но в любом случае вы сможете подтвердить личность.

Карл Андерсон
источник
OpenID 2.0 был недавно объявлен устаревшим и отключен Google в пользу OpenID Connect на основе OAuth, который предоставляет проверяемые токены идентификаторов .
Vadzim