Use Code Model

The Google Identity Services library enables users to request an authorization code from Google using either a browser based Popup or Redirect UX flow. This begins a secure OAuth 2.0 flow and results in an access token used to call Google APIs on a user's behalf.

OAuth 2.0 authorization code flow summary:

  • From a browser, with a gesture such as a button click, the Google Account owner requests an authorization code from Google.
  • Google responds, sending a unique authorization code either to a callback in your JavaScript web app running in the user's browser, or directly invokes your authorization code endpoint using a browser redirect.
  • Your backend platform hosts an authorization code endpoint and receives the code. After validation, this code is exchanged for per user access and refresh tokens using a request to Google's token endpoint.
  • Google validates the authorization code, confirms the request originated from your secure platform, issues access and refresh tokens, and returns the tokens by calling the login endpoint hosted by your platform.
  • Your login endpoint receives the access and refresh tokens, securely storing the refresh token for later use.

Initialize a Code Client

The google.accounts.oauth2.initCodeClient() method initializes a code client.

You can choose to share an auth code using either the Redirect or Popup mode user flow. With Redirect mode you host an OAuth2 authorization endpoint on your server and Google redirects the user-agent to this endpoint, sharing the auth code as a URL parameter. For Popup mode you define a JavaScript callback handler, which sends the authorization code to your server. Popup mode can be used to provide a seamless user experience without visitors having to leave your site.

To initialize a client for the:

  • Redirect UX flow, set ux_mode to redirect, and the value of redirect_uri to your platform's authorization code endpoint. The value must exactly match one of the authorized redirect URIs for the OAuth 2.0 client which you configured in the API Console. It must also conform to our Redirect URI validation rules.

  • Popup UX flow, set ux_mode to popup, and the value of callback to the name of the function you will use to send authorization codes to your platform.

Preventing CSRF attacks

To help prevent Cross-Site-Request-Forgery (CSRF) attacks slightly different techniques are employed for the Redirect and Popup mode UX flows. For Redirect mode, the OAuth 2.0 state parameter is used. See RFC6749 section 10.12 Cross-Site Request Forgery for more on generating and validating the state parameter. With Popup mode, you add a custom HTTP header to your requests, and then on your server confirm it matches the expected value and origin.

Choose a UX mode to view a code snippet showing auth code and CSRF handling:

Redirect mode

Initialize a client where Google redirects the user's browser to your authentication endpoint, sharing auth code as a URL parameter.

const client = google.accounts.oauth2.initCodeClient({
  client_id: 'YOUR_GOOGLE_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly',
  ux_mode: 'redirect',
  redirect_uri: "https://your.domain/code_callback_endpoint",
  state: "YOUR_BINDING_VALUE"
});

Initialize a client where the user's browser receives an auth code from Google and sends it to your server.

const client = google.accounts.oauth2.initCodeClient({
  client_id: 'YOUR_GOOGLE_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly',
  ux_mode: 'popup',
  callback: (response) => {
    const xhr = new XMLHttpRequest();
    xhr.open('POST', code_receiver_uri, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    // Set custom header for CRSF
    xhr.setRequestHeader('X-Requested-With', 'XmlHttpRequest');
    xhr.onload = function() {
      console.log('Auth code response: ' + xhr.responseText);
    };
    xhr.send('code=' + response.code);
  },
});

Trigger OAuth 2.0 Code Flow

Call the requestCode() method of the code client to trigger the user flow:

<button onclick="client.requestCode();">Authorize with Google</button>

This will require the user to sign-in to a Google Account and consent to share individual scopes prior to returning an authorization code either to your redirect endpoint or your callback handler.

Auth code handling

Google generates a unique per user authorization code which you receive and verify on your backend server.

For Popup mode, the handler specified by callback, running in the user's browser, relays the authorization code to an endpoint hosted by your platform.

For Redirect mode, a GET request is sent to the endpoint specified by redirect_url, sharing the authorization code in the URL code parameter. To receive the authorization code:

  • Create a new Authorization endpoint if you do not have an existing implementation, or

  • Update your existing endpoint to accept GET requests and URL parameters. Previously, a PUT request with the authorization code value in the payload was used.

Authorization endpoint

Your authorization code endpoint must handle GET requests with these URL query string parameters:

Name Value
authuser Request for user sign-in authentication
code An OAuth2 authorization code generated by Google
hd The hosted domain of the user account
prompt User consent dialog
scope Space separated list of one or more OAuth2 scopes to be authorized
state CRSF state variable

Example GET request with URL parameters to an endpoint named auth-code and hosted by example.com:

Request URL: https://www.example.com/auth-code?state=42a7bd822fe32cc56&code=4/0AX4XfWiAvnXLqxlckFUVao8j0zvZUJ06AMgr-n0vSPotHWcn9p-zHCjqwr47KHS_vDvu8w&scope=email%20profile%20https://www.googleapis.com/auth/calendar.readonly%20https://www.googleapis.com/auth/photoslibrary.readonly%20https://www.googleapis.com/auth/contacts.readonly%20openid%20https://www.googleapis.com/auth/userinfo.email%20https://www.googleapis.com/auth/userinfo.profile&authuser=0&hd=example.com&prompt=consent

When the authorization code flow is initiated by earlier JavaScript libraries, or by direct calls to Google OAuth 2.0 endpoints, a POST request is used.

Example POST request containing the authorization code as a payload in the HTTP request body:

Request URL: https://www.example.com/auth-code
Request Payload: 4/0AX4XfWhll-BMV82wi4YwbrSaTPaRpUGpKqJ4zBxQldU\_70cnIdh-GJOBZlyHU3MNcz4qaw

Validate the request

On your server do the following to help avoid CSRF attacks.

Check the value of the state parameter, for redirect mode.

Confirm the X-Requested-With: XmlHttpRequest header is set for popup mode.

You should then proceed with obtaining refresh and access tokens from Google only if you have first successfully verified the auth code request.

Get access and refresh tokens

After your backend platform receives an authorization code from Google and verifies the request, use the auth code to obtain access and refresh tokens from Google to make API calls.

Follow the instructions starting at Step 5: Exchange authorization code for refresh and access tokens of the Using OAuth 2.0 for Web Server Applications guide.

Managing tokens

Your platform securely stores refresh tokens. Delete stored refresh tokens when user accounts are removed, or user consent is revoked by google.accounts.oauth2.revoke or directly from https://myaccount.google.com/permissions.

Optionally, you may consider RISC to protect user accounts with Cross-Account Protection.

Typically, your backend platform will call Google APIs using an access token. If your web app will also directly call Google APIs from the user's browser you must implement a way to share the access token with your web application, doing so is out of scope of this guide. When following this approach and using the Google API Client Library for JavaScript use gapi.client.SetToken() to temporarily store the access token in browser memory, and enable the library to call Google APIs.