Como posso verificar um token de acesso à API de autenticação do Google?

134

Como posso verificar um token de acesso à autenticação do Google?

De alguma forma, preciso consultar o Google e perguntar: [o token de acesso fornecido] é válido para a conta do Google [[email protected]]?

Versão curta :
está claro como um token de acesso fornecido pelo Google Authentication Api :: OAuth Authentication for Web Applications pode ser usado para solicitar dados de vários serviços do Google. Não está claro como verificar se um determinado token de acesso é válido para uma determinada conta do Google. Eu gostaria de saber como.

Versão longa :
estou desenvolvendo uma API que usa autenticação baseada em token. Um token será retornado mediante o fornecimento de um nome de usuário + senha válidos ou mediante o fornecimento de um token de terceiros de qualquer um dos N serviços verificáveis.

Um dos serviços de terceiros será o Google, permitindo que um usuário se autentique no meu serviço usando sua Conta do Google. Mais tarde, isso será estendido para incluir contas do Yahoo, provedores confiáveis ​​de OpenID e assim por diante.

Exemplo esquemático de acesso baseado no Google:

texto alternativo http://webignition.net/images/figures/auth_figure002.png

A entidade 'API' está sob meu controle total. A entidade 'interface pública' é qualquer aplicativo baseado na Web ou na área de trabalho. Algumas interfaces públicas estão sob meu controle, outras não e outras ainda que eu talvez nunca saiba.

Portanto, não posso confiar no token fornecido à API na etapa 3. Ele será fornecido junto com o endereço de e-mail da conta do Google correspondente.

De alguma forma, preciso consultar o Google e perguntar: esse token de acesso é válido por [email protected] ?

Nesse caso, [email protected] é o identificador exclusivo da conta do Google - o endereço de e-mail que alguém usa para fazer login na conta do Google. Não se pode supor que seja um endereço do Gmail - alguém pode ter uma conta do Google sem ter uma conta do Gmail.

A documentação do Google indica claramente como, com um token de acesso, os dados podem ser recuperados de vários serviços do Google. Nada parece indicar como você pode verificar se um determinado token de acesso é válido em primeiro lugar.

Atualizar O token é válido para N serviços do Google. Não posso tentar um token em um serviço do Google como forma de verificá-lo, pois não saberei qual subconjunto de todos os serviços do Google um determinado usuário realmente usa.

Além disso, nunca usarei o token de acesso de autenticação do Google para acessar quaisquer serviços do Google, apenas como meio de verificar se um suposto usuário do Google é realmente quem eles dizem que são. Se houver outra maneira de fazer isso, estou feliz em tentar.

Jon Cram
fonte
De que serviço de autenticação específico é essa pergunta (OAuth, AuthSub, aplicativos instalados, ...)? Forneça um link mais detalhado.
Martin v. Löwis 11/12/08
@ Martin v. Löwis: O serviço 'Autenticação OAuth para aplicativos da Web' - atualizei o início da pergunta para refletir isso. Obrigado por apontar isso!
Jon Cram
artigo interessante sobre a verificação de chave do Google pode fornecer mais informações groups.google.com/group/Google-Maps-API/msg/f9e3c5ad3cbda4d7
dotjoe

Respostas:

138

Para verificação do usuário, basta postar obter o token de acesso como accessToken e publicá-lo e obter a resposta

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

você também pode tentar na barra de endereços dos navegadores, usar httppost e response em java também

resposta será como

{
     "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"
    }

O escopo é a permissão fornecida do accessToken. você pode verificar os IDs de escopo neste link

Atualização: nova publicação da API, conforme abaixo

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

A resposta será tão

 {
 // 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": "[email protected]",
 "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"
}

Para mais informações, https://developers.google.com/identity/sign-in/android/backend-auth

Vinoj John Hosan
fonte
11
Há uma versão mais recente do oauth2 - v3 do google. Veja o exemplo aqui: developers.google.com/identity/sign-in/android/backend-auth
AlikElzin-kilaka 4/16/16
30

você pode verificar um token de acesso à autenticação do Google usando este terminal:

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

Este é o ponto de extremidade de validação do Google V3 OAuth AccessToken, você pode consultar no documento do Google abaixo: (Na OAUTH 2.0 ENDPOINTSguia)

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

Nick Tsai
fonte
Para documentação de back-end - a fonte da documentação está aqui
eton_ceb 22/10/19
26

Ok, a maioria das respostas é válida, mas não totalmente correta. A ideia do JWT é que você possa validar o token sem a necessidade de entrar em contato com o emissor sempre. Você deve verificar o ID e verificar a assinatura do token com a chave pública conhecida do certificado que o Google usou para assinar o token.

Veja o próximo post por que e como fazer isso.

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

Remco
fonte
3
Mais votos por favor! The idea of JWT is that you can validate the token without the need to contact the issuer everytime.
Moritz Schmitz v. Hülst 23/10/19
sim! ppl são ddos-ing google se eles apenas chamarem google para informações sobre token
datdinhquoc 28/01
Você não pode fazer isso com os tokens de acesso do Google, porque eles não são JWTs. Verifique 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
fonte
2
Esta resposta é quase ainda válida. No entanto, Issued_to parece não estar mais definido. developers.google.com/accounts/docs/…
frostymarvelous
6

A resposta do fluxo de código oauth do Google, além de access_tokenretornos id_tokenque também contêm informações úteis para validação, na forma criptografada.

Uma coisa que torna os tokens de identificação úteis é o fato de que você pode transmiti-los por diferentes componentes do seu aplicativo. Esses componentes podem usar um token de ID como um mecanismo de autenticação leve que autentica o aplicativo e o usuário. Mas antes de poder usar as informações no token de ID ou confiar nelas como uma afirmação que o usuário autenticou, você deve validá-las.

A validação de um token de ID requer várias etapas:

  • Verifique se o token de ID é um JWT devidamente assinado com uma chave pública do Google apropriada.
  • Verifique se o valor de aud no token de ID é igual ao ID do cliente do seu aplicativo.
  • Verifique se o valor de iss no token de ID é igual a accounts.google.com ou https://accounts.google.com .
  • Verifique se o tempo de expiração (exp) do token de ID não passou.
  • Se você passou um parâmetro hd na solicitação, verifique se o token de ID possui uma reivindicação hd que corresponde ao seu domínio hospedado no Google Apps.

O link https://developers.google.com/identity/protocols/OpenIDConnect#validatinganidtoken possui exemplos de código para validação de tokens de ID.

Consulte também /security/37818/why-use-openid-connect-instead-of-plain-oauth .

Vadzim
fonte
1

De alguma forma, preciso consultar o Google e perguntar: esse token de acesso é válido por [email protected]?

Não. Tudo o que você precisa é solicitar o login padrão com o Login federado para usuários da conta do Google no seu domínio da API. E somente depois disso você poderá comparar o "ID do usuário persistente" com o que você possui na 'interface pública'.

O valor de região é usado na página de Login Federado do Google para identificar o site solicitante ao usuário. Também é usado para determinar o valor do ID do usuário persistente retornado pelo Google.

Então você precisa ser do mesmo domínio que 'interface pública'.

E não esqueça que o usuário precisa ter certeza de que sua API pode ser confiável;) Portanto, o Google perguntará ao usuário se isso permite que você verifique sua identidade.

Malx
fonte
1

Aqui está um exemplo usando o 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
fonte
0

Tente fazer uma solicitação autenticada pelo OAuth usando seu token para https://www.google.com/accounts/AuthSubTokenInfo . Isso está documentado apenas para funcionar no AuthSub, mas também no OAuth. Ele não informará para qual usuário o token é, mas informará para quais serviços ele é válido e a solicitação falhará se o token for inválido ou tiver sido revogado.

Jonathan
fonte
0

Um token de acesso arbitrário do OAuth não pode ser usado para autenticação, porque o significado do token está fora da especificação principal do OAuth. Poderia ser destinado a um único uso ou a uma janela de expiração restrita, ou poderia fornecer acesso que o usuário não deseja fornecer. Também é opaco, e o consumidor OAuth que o obteve talvez nunca tenha visto nenhum tipo de identificador de usuário.

Um provedor de serviços OAuth e um ou mais consumidores podem facilmente usar o OAuth para fornecer um token de autenticação verificável, e existem propostas e idéias para fazer isso por aí, mas um provedor de serviços arbitrário que fala apenas o OAuth Core não pode fornecer isso sem outra colaboração. coordenação com um consumidor. O método AuthSubTokenInfo REST específico do Google, junto com o identificador do usuário, está próximo, mas também não é adequado, pois pode invalidar o token ou o token pode expirar.

Se o seu ID do Google for um identificador OpenId e sua "interface pública" for um aplicativo da Web ou puder acessar o navegador do usuário, você provavelmente deverá usar o OpenID OP do Google.

O OpenID consiste apenas em enviar o usuário ao OP e obter uma asserção assinada de volta. A interação é exclusivamente para o benefício do PR. Não há token de longa duração ou outro identificador específico do usuário que possa ser usado para indicar que um RP autenticou com êxito um usuário com um OP.

Uma maneira de verificar uma autenticação anterior em relação a um identificador OpenID é apenas executar a autenticação novamente, assumindo que o mesmo user agent esteja sendo usado. O OP deve poder retornar uma afirmação positiva sem a interação do usuário (verificando um cookie ou certificado de cliente, por exemplo). O OP está livre para exigir outra interação do usuário, e provavelmente o fará se a solicitação de autenticação vier de outro domínio (meu OP me dá a opção de autenticar novamente esse RP específico sem interagir no futuro). E, no caso do Google, a interface do usuário que o usuário utilizou para obter o token OAuth pode não usar o mesmo identificador de sessão; portanto, o usuário precisará se autenticar novamente. Mas, em qualquer caso, você poderá afirmar a identidade.

Karl Anderson
fonte
O OpenID 2.0 foi reprovado e desativado pelo Google em favor do OpenID Connect baseado em OAuth, que fornece tokens de identificação verificáveis .
Vadzim