Google Identity
Introduction
Enable users to sign into apps and authorize apps to use Google services.
References
Google Identity
https://developers.google.com/identity
Using OAuth 2.0 to Access Google APIs
https://developers.google.com/identity/protocols/oauth2
OAuth 2.0 Playground
https://developers.google.com/oauthplayground
Google API Client Libraries (Java, Python, Node.js, Go, etc.)
https://developers.google.com/api-client-library
Node.js OAuth2 client
https://github.com/googleapis/google-api-nodejs-client#oauth2-client
Google OAuth “invalid_grant” nightmare — and how to fix it
https://blog.timekit.io/google-oauth-invalid-grant-nightmare-and-how-to-fix-it-9f4efaf1da35
Google API OAuth 2.0 basic concepts
Client ID and client secret
Visit the Google API Console to obtain OAuth 2.0 credentials such as a client ID and client secret that are known to both Google and your application. The set of values varies based on what type of application you are building. For example, a JavaScript application does not require a secret, but a web server application does.
Authorization code
If the user grants at least one permission, the Google Authorization Server sends your application an access token (or an authorization code that your application can use to obtain an access token) and a list of scopes of access granted by that token. If the user does not grant the permission, the server returns an error.
The application can exchange the authorization code for an access token and a refresh token.
Access token
The client application sends the access token to the Google API that you want to access.
Refresh token
Access tokens have limited lifetimes. If your application needs access to a Google API beyond the lifetime of a single access token, it can obtain a refresh token. A refresh token allows your application to obtain new access tokens.
Note: Save refresh tokens in secure long-term storage and continue to use them as long as they remain valid. Limits apply to the number of refresh tokens that are issued per client-user combination, and per user across all clients, and these limits are different. If your application requests enough refresh tokens to go over one of the limits, older refresh tokens stop working.
Refresh token expiration
You must write your code to anticipate the possibility that a granted refresh token might no longer work. A refresh token might stop working for one of these reasons:
The user has revoked your app's access.
The refresh token has not been used for six months.
The user changed passwords and the refresh token contains Gmail scopes.
The user account has exceeded a maximum number of granted (live) refresh tokens.
The user belongs to a Google Cloud Platform organization that has session control policies in effect.
Token size
Tokens can vary in size, up to the following limits:
Authorization codes: 256 bytes
Access tokens: 2048 bytes
Refresh tokens: 512 bytes
Sample using the OAuth 2.0 Playground
In this sample:
Step 1: Authorize APIs and get authorization code
Step 2: Exchange authorization code for tokens (access_token and refresh_token)
Step 3: Consume API using the access_token
Step 1: Authorize APIs and get authorization code
Let's get the authorization code for scopes:
https://www.googleapis.com/auth/gmail.send, https://www.googleapis.com/auth/userinfo.email
Request:
HTTP/1.1 302 Found
Location: https://accounts.google.com/o/oauth2/v2/auth?redirect_uri=https%3A%2F%2Fdevelopers.google.com%2Foauthplayground&prompt=consent&response_type=code&client_id=f4k308718192.apps.googleusercontent.com&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgmail.send+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&access_type=offline
Response:
GET /oauthplayground/?code=4/0AX4XfWi7QNI2QpWdDTEjBv89-yrCBdizOLwYfg4EzQTwKeyZlwHC8wRQE0PPH6CXYde5fA&scope=email%20openid%20https://www.googleapis.com/auth/userinfo.email&authuser=0&prompt=consent HTTP/1.1
Host: developers.google.com
Step 2: Exchange authorization code for tokens (access_token and refresh_token)
Request:
POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-length: 261
content-type: application/x-www-form-urlencoded
user-agent: google-oauth-playground
code=4%2F0AX4XfWi7QNI2QpWdDTEjBv89-yrCBdizOLwYfg4EzQTwKeyZlwHC8wRQE0PPH6CXYde5fA&redirect_uri=https%3A%2F%2Fdevelopers.google.com%2Foauthplayground&client_id=f4ke08718192.apps.googleusercontent.com&client_secret=************&scope=&grant_type=authorization_code
Response:
HTTP/1.1 200 OK
Content-length: 1297
X-xss-protection: 0
X-content-type-options: nosniff
Transfer-encoding: chunked
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Vary: Origin, X-Origin, Referer
Server: scaffolding on HTTPServer2
-content-encoding: gzip
Pragma: no-cache
Cache-control: no-cache, no-store, max-age=0, must-revalidate
Date: Wed, 09 Feb 2022 15:53:29 GMT
X-frame-options: SAMEORIGIN
Alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
Content-type: application/json; charset=utf-8
{
"access_token": "f4ke.A0ARrdaM_im_griYib5SF2Nq37IptJQxwF11n166XMgnPG-JXd7KCuOtgw-FtexX97ZIgi1WKPzROPLM39uPzT2NrDBm7ZDHGyEPPtqCWa9Sm9zAEe5aAGex_-t6J75Pg1rPu6nRoiWSc0vX1c5Nk6z6vmZka6",
"id_token": "f4K3bGciOiJSUzI1NiIsImtpZCI6IjE4MmU0NTBhMzVhMjA4MWZhYTFkOWFlMWQyZDc1YTBmMjNkOTFkZjgiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhenAiOiI0MDc0MDg3MTgxOTIuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJhdWQiOiI0MDc0MDg3MTgxOTIuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMDA4NDA0OTIwMjU3OTkzODQ3ODUiLCJlbWFpbCI6Impvc2UubWFudWVsLnJvZHJpZ3Vlei5tb3Jlbm9AZ21haWwuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImF0X2hhc2giOiJiVEVyZnpjMFhBWl94UmFvcTgxSnRnIiwiaWF0IjoxNjQ0NDIyMDA5LCJleHAiOjE2NDQ0MjU2MDl9.Tq9t5skdNgGzJf4uCeKNogqFtUuKbwbggbn6G4ID2cqm7Io6CajUrnsr5kImeXvHVy91X-ygQGPw8PNi58msYLcb1xO74mVpbEOkF4OnKn5oaatHrLfxTL8T0-_dE844i8v26JfDdtP5dnf_2SKBxn2H5HPc2-2UqDQMSU0yhEvQZ-eoxPF1U-OZgCa3HTPf2GSt6I2gBnSePBc16Ac7DLwHUZHS7yfQQU3_10xj0Lju_W_uw6OelGCFGEzsohCRhXUmmG2GHc_T1hv1HE5Ot-MewvFRNeQOAwvPAYqlONwkpyr2Lw7GkmbjbcJAal1VCUH9zGy5VpbztLhukQ3Tcg",
"expires_in": 3599,
"token_type": "Bearer",
"scope": "openid https://www.googleapis.com/auth/userinfo.email",
"refresh_token": "1//f4k3p57hWDhdHCgYIARAAGAQSNwF-L9IrtTLbf7yCwko7Jc3EYhTUBQptkr53hY2DbVfjIMHuf8LzYh1aeVfwWawWyoUa0vuHiMI"
}
Step 3: Consume API using the access_token
Eg: Getting email address of the user.
Request:
GET /oauth2/v3/userinfo HTTP/1.1
Host: www.googleapis.com
Content-length: 0
Authorization: Bearer f4ke.A0ARrdaM_im_griYib5SF2Nq37IptJQxwF11n166XMgnPG-JXd7KCuOtgw-FtexX97ZIgi1WKPzROPLM39uPzT2NrDBm7ZDHGyEPPtqCWa9Sm9zAEe5aAGex_-t6J75Pg1rPu6nRoiWSc0vX1c5Nk6z6vmZka6
Response:
HTTP/1.1 200 OK
Content-length: 226
X-xss-protection: 0
Content-location: https://www.googleapis.com/oauth2/v3/userinfo
X-content-type-options: nosniff
Transfer-encoding: chunked
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Vary: Origin, X-Origin, Referer
Server: ESF
-content-encoding: gzip
Pragma: no-cache
Cache-control: no-cache, no-store, max-age=0, must-revalidate
Date: Wed, 09 Feb 2022 15:59:11 GMT
X-frame-options: SAMEORIGIN
Alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
Content-type: application/json; charset=utf-8
{
"picture": "https://lh3.googleusercontent.com/a-/F4k34Gg5YlP7xL9tp-7JCoQmNGwj-550qGKU6wPoKfB7fQ=s96-c",
"email_verified": true,
"sub": "100840492025799384785",
"email": "f4k3@gmail.com"
}
Sample refreshing an access token (offline access)
Example based on:
https://developers.google.com/identity/protocols/oauth2/web-server#offline
To refresh an access token, your application sends an HTTPS POST request to Google's authorization server (https://oauth2.googleapis.com/token) that includes the following parameters:
client_id - The client ID obtained from the API Console.
client_secret - The client secret obtained from the API Console.
grant_type - As defined in the OAuth 2.0 specification, this field's value must be set to refresh_token.
refresh_token - The refresh token returned from the authorization code exchange.
Request
POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded
client_id=your_client_id&
client_secret=your_client_secret&
refresh_token=refresh_token&
grant_type=refresh_token
Response
{
"access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
"expires_in": 3920,
"scope": "https://www.googleapis.com/auth/drive.metadata.readonly",
"token_type": "Bearer"
}