¿Cómo puedo verificar un token de acceso a la API de autenticación de Google?

134

¿Cómo puedo verificar un token de acceso de autenticación de Google?

Necesito consultar de alguna manera a Google y preguntar: ¿Es [dado el token de acceso] válido para la cuenta de Google [[email protected]]?

Versión corta :
está claro cómo un token de acceso suministrado a través de la autenticación de Google Api :: OAuth Authentication for Web Applications se puede utilizar para luego solicitar datos de una gama de servicios de Google. No está claro cómo verificar si un token de acceso determinado es válido para una cuenta de Google determinada. Me gustaría saber cómo.

Versión larga :
estoy desarrollando una API que usa autenticación basada en token. Se devolverá un token al proporcionar un nombre de usuario + contraseña válidos o al proporcionar un token de terceros de cualquiera de los N servicios verificables.

Uno de los servicios de terceros será Google, lo que permitirá a un usuario autenticarse contra mi servicio utilizando su cuenta de Google. Posteriormente, esto se ampliará para incluir cuentas de Yahoo, proveedores de OpenID de confianza, etc.

Ejemplo esquemático de acceso basado en Google:

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

La entidad 'API' está bajo mi control total. La entidad de 'interfaz pública' es cualquier aplicación web o de escritorio. Algunas interfaces públicas están bajo mi control, otras no lo estarán y otras aún no las conozco.

Por lo tanto, no puedo confiar en el token suministrado a la API en el paso 3. Esto se proporcionará junto con la dirección de correo electrónico de la cuenta de Google correspondiente.

Necesito consultar de alguna manera a Google y preguntar: ¿Es válido este token de acceso por [email protected] ?

En este caso, [email protected] es el identificador único de la cuenta de Google: la dirección de correo electrónico que alguien usa para iniciar sesión en su cuenta de Google. No se puede suponer que se trata de una dirección de Gmail: alguien puede tener una cuenta de Google sin tener una cuenta de Gmail.

La documentación de Google establece claramente cómo, con un token de acceso, los datos se pueden recuperar de varios servicios de Google. Nada parece indicar cómo puede verificar si un token de acceso dado es válido en primer lugar.

Actualización El token es válido para N servicios de Google. No puedo probar un token contra un servicio de Google como medio para verificarlo, ya que no sabré qué subconjunto de todos los servicios de Google utiliza un usuario determinado.

Además, nunca usaré el token de acceso de autenticación de Google para acceder a ningún servicio de Google, simplemente como un medio para verificar que un supuesto usuario de Google sea realmente quien dice ser. Si hay otra forma de hacerlo, estoy feliz de intentarlo.

Jon Cram
fuente
¿De qué servicio de autenticación específica se trata esta pregunta (OAuth, AuthSub, Aplicaciones instaladas, ...)? Proporcione un enlace más detallado.
Martin v. Löwis
@Martin v. Löwis: El servicio 'Autenticación OAuth para aplicaciones web' - He actualizado el inicio de la pregunta para reflejar esto. ¡Gracias por señalar esto!
Jon Cram
un artículo interesante sobre la verificación de la clave de Google podría brindar más información groups.google.com/group/Google-Maps-API/msg/f9e3c5ad3cbda4d7
dotjoe

Respuestas:

138

Para la verificación del usuario, simplemente publique obtener el token de acceso como accessToken y publíquelo y obtenga la respuesta

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

puede probar en la barra de direcciones en los navegadores también, use httppost y respuesta en java también

la respuesta 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"
    }

El alcance es el permiso otorgado por accessToken. puede consultar los identificadores de alcance en este enlace

Actualización: nueva publicación de API como se muestra a continuación

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

La respuesta será como

 {
 // 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 obtener más información, https://developers.google.com/identity/sign-in/android/backend-auth

Vinoj John Hosan
fuente
11
Hay una versión más nueva para Google's oauth2 - v3. Ver ejemplo aquí: developers.google.com/identity/sign-in/android/backend-auth
AlikElzin-kilaka
30

puede verificar un token de acceso de autenticación de Google utilizando este punto final:

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

Este es el punto final de validación de Google V3 OAuth AccessToken, puede consultar el documento de Google a continuación: (En la OAUTH 2.0 ENDPOINTSpestaña)

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

Nick Tsai
fuente
Para la documentación backend - fuente de documentación está aquí
eton_ceb
26

Ok, la mayoría de las respuestas son válidas pero no del todo correctas. La idea de JWT es que puede validar el token sin la necesidad de contactar al emisor cada vez. Debe verificar la identificación y verificar la firma del token con la clave pública conocida del certificado que Google utilizó para firmar el token.

Vea la próxima publicación por qué y cómo hacer esto.

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

Remco
fuente
3
¡Más 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
¡si! ppl está haciendo ddos-ing google si solo llama a google para obtener información de token
datdinhquoc
No puede hacer esto con los tokens de acceso de Google porque no son JWT. Consulte 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
fuente
2
Esta respuesta es casi válida todavía. Issued_to parece que ya no está configurado. developers.google.com/accounts/docs/…
frostymarvelous
6

Respuesta de flujo de código de Google oauth además de access_tokendevoluciones id_tokenque contienen información útil para la validación en forma cifrada.

Una cosa que hace que los tokens de ID sean útiles es el hecho de que puede pasarlos por diferentes componentes de su aplicación. Estos componentes pueden usar un token de ID como un mecanismo de autenticación ligero que autentica la aplicación y el usuario. Pero antes de que pueda usar la información en el token de ID o confiar en ella como una afirmación de que el usuario se ha autenticado, debe validarla.

La validación de un token de ID requiere varios pasos:

  • Verifique que el token de ID sea un JWT que esté debidamente firmado con una clave pública de Google adecuada.
  • Verifique que el valor de aud en el token de ID sea igual al ID de cliente de su aplicación.
  • Verifique que el valor de iss en el token de ID sea igual a accounts.google.com o https://accounts.google.com .
  • Verifique que el tiempo de expiración (exp) del token de ID no haya pasado.
  • Si pasó un parámetro hd en la solicitud, verifique que el token de ID tenga un reclamo hd que coincida con su dominio alojado de Google Apps.

El enlace https://developers.google.com/identity/protocols/OpenIDConnect#validatinganidtoken tiene ejemplos de código para la validación de tokens de ID.

Consulte también /security/37818/why-use-openid-connect-instead-of-plain-oauth .

Vadzim
fuente
1

Necesito consultar de alguna manera a Google y preguntar: ¿Es válido este token de acceso por [email protected]?

No. Todo lo que necesita es solicitar un inicio de sesión estándar con Inicio de sesión federado para usuarios de la cuenta de Google desde su dominio API. Y solo después de eso, podría comparar la "identificación de usuario persistente" con una que tenga de 'interfaz pública'.

El valor de reino se usa en la página de inicio de sesión federado de Google para identificar el sitio solicitante para el usuario. También se utiliza para determinar el valor de la identificación de usuario persistente devuelta por Google.

Por lo tanto, debe ser del mismo dominio que 'interfaz pública'.

Y no olvide que el usuario debe asegurarse de que su API sea confiable;) Google le preguntará al usuario si le permite verificar su identidad.

Malx
fuente
1

Aquí hay un ejemplo usando 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
fuente
0

Intente realizar una solicitud autenticada por OAuth usando su token a https://www.google.com/accounts/AuthSubTokenInfo . Esto solo está documentado para funcionar en AuthSub, pero también funciona para OAuth. No le dirá para qué usuario es el token, pero le dirá para qué servicios es válido, y la solicitud fallará si el token no es válido o ha sido revocado.

Jonathan
fuente
0

Un token de acceso OAuth arbitrario no se puede usar para la autenticación, porque el significado del token está fuera de la especificación OAuth Core. Podría estar destinado a un solo uso o una ventana de vencimiento estrecha, o podría proporcionar acceso que el usuario no quiere dar. También es opaco, y el consumidor de OAuth que lo obtuvo nunca podría haber visto ningún tipo de identificador de usuario.

Un proveedor de servicios de OAuth y uno o más consumidores podrían usar fácilmente OAuth para proporcionar un token de autenticación verificable, y hay propuestas e ideas para hacer esto, pero un proveedor de servicios arbitrario hablando solo OAuth Core no puede proporcionar esto sin otra ordenación con un consumidor. El método REST AuthSubTokenInfo específico de Google, junto con el identificador del usuario, está cerca, pero tampoco es adecuado, ya que podría invalidar el token o el token podría expirar.

Si su ID de Google es un identificador de OpenId y su 'interfaz pública' es una aplicación web o puede abrir el navegador del usuario, entonces probablemente debería usar el OP de OpenID de Google.

OpenID consiste en enviar al usuario al OP y recuperar una afirmación firmada. La interacción es únicamente para el beneficio del RP. No hay un token de larga duración u otro identificador específico del usuario que pueda usarse para indicar que un RP ha autenticado con éxito a un usuario con un OP.

Una forma de verificar una autenticación previa contra un identificador OpenID es simplemente realizar la autenticación nuevamente, suponiendo que se esté utilizando el mismo agente de usuario. El OP debe poder devolver una afirmación positiva sin interacción del usuario (verificando una cookie o un certificado de cliente, por ejemplo). El OP es libre de requerir otra interacción del usuario, y probablemente lo hará si la solicitud de autenticación proviene de otro dominio (mi OP me da la opción de volver a autenticar este RP en particular sin interactuar en el futuro). Y en el caso de Google, la interfaz de usuario que el usuario pasó para obtener el token OAuth podría no usar el mismo identificador de sesión, por lo que el usuario tendrá que volver a autenticarse. Pero en cualquier caso, podrás afirmar la identidad.

Karl Anderson
fuente
OpenID 2.0 fue recientemente desaprobado y deshabilitado por Google a favor de OpenID Connect basado en OAuth que proporciona tokens de identificación verificables .
Vadzim