2011-11-29 14 views
51

Utilicé el inicio de sesión de Facebook para identificar a los usuarios. Cuando llega un nuevo usuario, guardo su ID de usuario en mi base de datos. La próxima vez que vienen, reconocí su identificación de Facebook y sé qué usuario es en mi base de datos.¿Cómo identificar a un usuario de Google OAuth2?

Ahora estoy tratando de hacer lo mismo con Google OAuth2, pero ¿cómo puedo reconocer a los usuarios?

Google me envía varios códigos y tokens (access_token, id_token, refresh_token), sin embargo, ninguno de ellos es constante. Es decir, si cierro la sesión y vuelvo a iniciar sesión 2 minutos después, los 3 valores han cambiado. ¿Cómo puedo identificar al usuario de forma única?

estoy usando la biblioteca cliente PHP: "¿Quién es este" https://code.google.com/p/google-api-php-client/

Respuesta

26

que este método inserta en google-api-php-cliente/src/apiClient.php:

public function getUserInfo() 
{ 
    $req = new apiHttpRequest('https://www.googleapis.com/oauth2/v1/userinfo'); 
    // XXX error handling missing, this is just a rough draft 
    $req = $this->auth->sign($req); 
    $resp = $this->io->makeRequest($req)->getResponseBody(); 
    return json_decode($resp, 1); 
} 

Ahora puedo llamar:

$client->setAccessToken($_SESSION[ 'token' ]); 
$userinfo = $client->getUserInfo(); 

Devuelve un array como esto (además e-mail si se ha solicitado que alcance):

Array 
(
    [id] => 1045636599999999999 
    [name] => Tim Strehle 
    [given_name] => Tim 
    [family_name] => Strehle 
    [locale] => de 
) 

La solución se originó a partir de este hilo: https://groups.google.com/forum/#!msg/google-api-php-client/o1BRsQ9NvUQ/xa532MxegFIJ

+4

Tenga en cuenta que Google ha cambiado recientemente la respuesta y que 'id_token' ahora contiene el identificador estático en la clave' sub' en lugar de la clave 'id' como en el ejemplo anterior. AFAIK, este cambio es su interpretación del protocolo OpenID Connect. Desafortunadamente, mientras escribo esto, las respuestas parecen un tanto aleatorias: a veces es 'id' y a veces es' sub', así que necesito apoyar ambas. –

1

es esencialmente un servicio; debe solicitar acceso a él como ámbito y luego realizar una solicitud al perfil de Google servidor de recursos para obtener la identidad. Ver OAuth 2.0 for Login para los detalles.

+0

Esto parece ser más técnicamente correcto, pero carece de los detalles adicionales que la respuesta tiene actualmente aceptado. Combina las dos respuestas y tienes oro. –

76

Como otros han mencionado, puede enviar un GET a https://www.googleapis.com/oauth2/v3/userinfo, usando el portador OAuth2 de token que acaba de recibir, y obtendrá una respuesta con un poco de información sobre el usuario (identificación, nombre, etc.).

También vale la pena mencionar que Google implementa OpenID Connect y que este punto final de información del usuario es solo una parte de él.

OpenID Connect es una capa de autenticación en la parte superior de OAuth2. Al intercambiar una autorización code en el punto final del token de Google, se obtiene un token de acceso (el parámetro access_token), así como un token de ID de OpenID Connect (el parámetro id_token).

Ambos estos tokens son JWT (JSON Token web, http://tools.ietf.org/html/draft-ietf-oauth-json-web-token).

Si las decodifica, obtendrá algunas afirmaciones, incluida la id del usuario. Si vincula este ID a un usuario en su base de datos, puede identificarlos inmediatamente sin tener que hacer una GET extra de userinfo (ahorra tiempo).

Como se menciona en los comentarios, estos tokens están firmados con la clave privada de Google y es posible que desee verificar la firma mediante la clave pública de Google (https://www.googleapis.com/oauth2/v3/certs) para asegurarse de que sean auténticos.

Puede ver lo que hay en un JWT pegándolo en https://jwt.io/ (desplácese hacia abajo para el depurador JWT). Las afirmaciones se ven algo como:

{ 
    "iss":"accounts.google.com", 
    "id":"1625346125341653", 
    "cid":"8932346534566-hoaf42fgdfgie1lm5nnl5675g7f167ovk8.apps.googleusercontent.com", 
    "aud":"8932346534566-hoaf42fgdfgie1lm5nnl5675g7f167ovk8.apps.googleusercontent.com", 
    "token_hash":"WQfLjdG1mDJHgJutmkjhKDCdA", 
    "iat":1567923785, 
    "exp":1350926995 
} 

También hay bibliotecas para varios lenguajes de programación para decodificar programáticamente JWTs.

PS: para obtener una lista actualizada de las URL y las funciones admitidas por el proveedor de OpenID Connect de Google, puede verificar esa URL: https://accounts.google.com/.well-known/openid-configuration.

+1

Sí, pero para utilizar esta información de forma segura, debe verificar la signatura del JWT, para lo cual necesitas la clave pública. ¿Alguna idea de dónde google pone a disposición sus claves públicas? – jazmit

+7

OK, lo encontré: https://www.googleapis.com/oauth2/v1/certs También debo señalar que hacer la verificación es absolutamente necesario; de lo contrario, un atacante podría iniciar sesión fácilmente en su aplicación utilizando cualquier registro ya registrado. cuenta Google. – jazmit

+0

@jamesinchina ¿Y cómo crees que es posible este ataque si la información en sí proviene directamente de Google, no de un atacante? – stroncium

1

Altough JWT se puede validar localmente con la clave pública, (Google APIs Client Library descarga y almacena en caché las claves públicas automáticamente) marcando el token en el lado de Google a través del https://www.googleapis.com/oauth2/v1/tokeninfo endpoint es necesario comprobar si el acceso para la aplicación ha sido revocado desde la creación del token.

9

Cabe mencionar que la API de OpenID Connect ya no devuelve el atributo id.

Ahora es el atributo sub que sirve como una identificación de usuario única.

Ver Google Dev OpenID Connect UserInfo

+1

No estoy seguro de que sea correcto. A pesar de lo que dice el documento, si reinicio mi servidor de autenticación, borro el caché y vuelvo a iniciar sesión, el 'sub' es diferente. – HockeyJ

+0

¿Alguien más tenía el problema de HockeyJ con 'sub' cambio para el mismo inicio de sesión? – dardawk

Cuestiones relacionadas