Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to identify a Google OAuth2 user?

I used Facebook login to identify users. When a new user comes, I store their userID in my database. Next time they come, I recognized their Facebook ID and I know which user it is in my database.

Now I am trying to do the same with Google's OAuth2, but how can I recognize the users?

Google sends me several codes and tokens (access_token, id_token, refresh_token), however none of them are constant. Meaning if I log out and log back in 2 minutes later, all 3 values have changed. How can I uniquely identify the user?

I am using their PHP client library: https://code.google.com/p/google-api-php-client/

like image 630
Nathan H Avatar asked Nov 29 '11 13:11

Nathan H


People also ask

How can I get user information from OAuth?

If the authorization server supports OpenID Connect, there are two standard ways to get user information. One is to request the authorization server to issue an ID token which contains user information. The other is to access UserInfo Endpoint. See OpenID Connect Core 1.0 for details.

Is Google OAuth2 login?

Google APIs use the OAuth 2.0 protocol for authentication and authorization. Google supports common OAuth 2.0 scenarios such as those for web server, client-side, installed, and limited-input device applications.


3 Answers

As others have mentioned, you can send a GET to https://www.googleapis.com/oauth2/v3/userinfo, using the OAuth2 bearer token you just received, and you will get a response with some information about the user (id, name, etc.).

It's also worth mentioning that Google implements OpenID Connect and that this user info endpoint is just one part of it.

OpenID Connect is an authentication layer on top of OAuth2. When exchanging a authorization code at Google's token endpoint, you get an access token (the access_token parameter) as well as an OpenID Connect ID token (the id_token parameter).

Both these tokens are JWT (JSON Web Token, https://datatracker.ietf.org/doc/html/draft-ietf-oauth-json-web-token).

If you decode them, you'll get some assertions, including the id of the user. If you link this ID to a user in your DB, you can immediately identify them without having to do an extra userinfo GET (saves time).

As mentioned in the comments, these tokens are signed with Google's private key and you may want to verify the signature using Google's public key (https://www.googleapis.com/oauth2/v3/certs) to make sure they are authentic.

You can see what's in a JWT by pasting it at https://jwt.io/ (scroll down for the JWT debugger). The assertions look something like:

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

There are also libraries for various programming languages to programatically decode JWTs.

PS: to get an up to date list of URLs and features supported by Google's OpenID Connect provider you can check that URL: https://accounts.google.com/.well-known/openid-configuration.

like image 60
Christophe L Avatar answered Oct 22 '22 11:10

Christophe L


I inserted this method into google-api-php-client/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);  
}

Now I can call:

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

It returns an array like this (plus e-mail if that scope has been requested):

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

The solution originated from this thread: https://groups.google.com/forum/#!msg/google-api-php-client/o1BRsQ9NvUQ/xa532MxegFIJ

like image 43
Tim Strehle Avatar answered Oct 22 '22 11:10

Tim Strehle


It should be mentioned, that the OpenID Connect API returns no id attribute anymore.

It's now the sub attribute which serves as a unique user identification.

See Google Dev OpenID Connect UserInfo

like image 20
blang Avatar answered Oct 22 '22 11:10

blang