## Overview

*OAuth-based Sign in with Google Streamlined linking* adds Sign in with Google
on top of [OAuth linking](https://developers.google.com/identity/account-linking/oauth-linking). This provides a seamless linking
experience for Google users, and optionally enables account creation, which
allows the user to create a new account on your service using their Google
Account.

To perform account linking with OAuth and Sign in with Google, follow these
general steps:

1. First, ask the user to give consent to access their Google profile.
2. Use the information in their profile to check if the user account exists.
3. For existing users, link the accounts.
4. If you cannot find a match for the Google user in your authentication system, validate the ID token received from Google. If your service supports account creation, you can then create a user based on the profile information contained in the ID token.

![This figure shows the steps for a user to link their Google account using the streamlined linking flow. The first screenshot shows how a user can select your app for linking. The second screenshot lets the user confirm whether or not they have an existing account on your service. The third screenshot lets the user select the Google account they want to link with. The fourth screenshot shows the confirmation for linking their Google account with your app. The fifth screenshot shows a successfully linked user account in the Google app.](https://developers.google.com/static/identity/account-linking/images/streamlined-linking-flow.png) Account Linking on a user's phone with Streamlined Linking

**Figure 1**. Account Linking on a user's phone with Streamlined Linking

### Streamlined Linking: OAuth + Sign in with Google Flow

The following sequence diagram details interactions between the User, Google,
and your token exchange endpoint for Streamlined Linking.
User Google App / Server Your Token Exchange Endpoint Your API 1. User initiates linking 2. Request Sign in with Google 3. Sign in with Google 4. check intent (JWT Assertion) 5. account_found: true/false If account found: 6. get intent If no account: 6. create intent 7. access_token, refresh_token 8. Store user tokens 9. Access user resources **Figure 2.** The sequence of events in the Streamlined Linking flow.

### Roles and responsibilities

The following table defines the roles and responsibilities of the actors in the
Streamlined Linking flow.

| Actor / Component | GAL Role | Responsibilities |
|---|---|---|
| **Google App / Server** | OAuth Client | Obtains user consent for Sign in with Google, passes identity assertions (JWT) to your server, and securely stores the resulting tokens. |
| **Your Token Exchange Endpoint** | Identity Provider / Authorization Server | Validates identity assertions, checks for existing accounts, handles the required account linking intents (`check`, `get`) and optional `create` intent, and issues tokens based on the requested intents. |
| **Your Service API** | Resource Server | Provides access to user data when presented with a valid access token. |

## Requirements for Streamlined Linking

- Implement the [basic OAuth linking](https://developers.google.com/identity/account-linking/oauth-linking) flow. Your service must support OAuth 2.0-compliant *authorization* and *token exchange* endpoints.
- Your *token exchange* endpoint must support [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) assertions and implement the required [`check`](https://developers.google.com/identity/account-linking/oauth-with-sign-in-linking#check_for_an_existing_user_account_check_intent) and [`get`](https://developers.google.com/identity/account-linking/oauth-with-sign-in-linking#handle_automatic_linking_get_intent) intents, and optionally the [`create`](https://developers.google.com/identity/account-linking/oauth-with-sign-in-linking#handle_account_creation_using_sign_in_with_google_create_intent) intent.

> [!NOTE]
> **Note:** These intents must be implemented in the same *token exchange* endpoint you created for the [basic OAuth linking](https://developers.google.com/identity/account-linking/oauth-linking) flow. **Do not create a
> different endpoint to handle these intents**.

- [Register your Google API Client ID](https://developers.google.com/identity/account-linking/oauth-with-sign-in-linking#get_your_google_api_client_id).

### Decision Logic for Streamlined Linking

The following logic determines how intents are called during the Streamlined
Linking flow:

1. Does the user have an account in your authentication system? (User decides by selecting YES or NO)
   1. YES : Does the user use the email associated with their Google Account to sign into your platform? (User decides by selecting YES or NO)
      1. YES : Does the user have a matching account in your authentication system? ([`check` intent](https://developers.google.com/identity/account-linking/oauth-with-sign-in-linking#check_for_an_existing_user_account_check_intent) is called to confirm)
         1. YES : [`get` intent](https://developers.google.com/identity/account-linking/oauth-with-sign-in-linking#handle_automatic_linking_get_intent) is called and the account is linked if get intent returns successfully.
         2. NO : Create New Account? (User decides by selecting YES or NO; applicable only if your service supports account creation)
            1. YES : [`create` intent](https://developers.google.com/identity/account-linking/oauth-with-sign-in-linking#handle_account_creation_using_sign_in_with_google_create_intent) is called and the account is linked if create intent returns successfully.
            2. NO : The OAuth linking flow is triggered, the user is directed to their browser, and the user is given the option to link with a different email.
      2. NO : The [OAuth linking flow](https://developers.google.com/identity/account-linking/oauth-linking) is triggered, the user is directed to their browser, and the user is given the option to link with a different email.
   2. NO : Does the user have a matching account in your authentication system? ([`check` intent](https://developers.google.com/identity/account-linking/oauth-with-sign-in-linking#check_for_an_existing_user_account_check_intent) is called to confirm)
      1. YES : [`get` intent](https://developers.google.com/identity/account-linking/oauth-with-sign-in-linking#handle_automatic_linking_get_intent) is called and the account is linked if get intent returns successfully.
      2. NO : If your service supports account creation, the [`create` intent](https://developers.google.com/identity/account-linking/oauth-with-sign-in-linking#handle_account_creation_using_sign_in_with_google_create_intent) is called and the account is linked if create intent returns successfully. If account creation is not supported, your endpoint should return HTTP 401 linking_error to trigger the fallback OAuth linking flow.

## Implementation Recipe

Your token exchange endpoint must implement the required `check` and `get`
intents, and optionally the `create` intent to support Streamlined Linking.

Follow these steps to handle the different intents:

#### Check for an existing user account (check intent)

Google calls your token exchange endpoint to verify if the Google user exists
in your system. For parameter details, see [Streamlined Linking
Intents](https://developers.google.com/identity/account-linking/your-api-reference#handle_streamlined_linking_intents).

##### Implementation Recipe

To handle the required `check` intent, perform the following actions:

1. **Validate the request**:

   - Verify `client_id`, `client_secret`, and `grant_type` (must be `urn:ietf:params:oauth:grant-type:jwt-bearer`).
   - Validate the `assertion` (JWT) using the criteria in [JWT
     Validation](https://developers.google.com/identity/account-linking/your-api-reference#jwt_validation).
2. **Lookup user**:

   - Check if the Google Account ID (`sub`) or email address in the JWT matches a user in your database.
3. **Respond**:

   - If found: Return HTTP `200 OK` with `{"account_found": "true"}`.
   - If not found: Return HTTP `404 Not Found` with `{"account_found": "false"}`.

#### Handle automatic linking (get intent)

If the account exists, Google calls your endpoint with `intent=get` to retrieve
tokens. For parameter details, see [Streamlined Linking
Intents](https://developers.google.com/identity/account-linking/your-api-reference#handle_streamlined_linking_intents).

##### Implementation Recipe

To handle the required `get` intent, perform the following actions:

1. **Validate the request**:

   - Verify `client_id`, `client_secret`, and `grant_type`.
   - Validate the `assertion` (JWT).
2. **Lookup user**:

   - Verify the user exists using the `sub` or `email` claim.
3. **Respond**:

   - If successful: Generate and return `access_token`, `refresh_token`, and `expires_in` in a JSON response (HTTP `200 OK`).
   - If linking fails: Return HTTP `401 Unauthorized` with `{"error": "linking_error"}` and an optional `login_hint` to fall back to standard OAuth linking.

#### Handle account creation using Sign in with Google (create intent)

> [!NOTE]
> **Note:** Supporting the `create` intent is optional. The required intents for Streamlined Linking are `check` and `get`.

If your service supports account creation and no account exists, Google calls
your endpoint with `intent=create` to create a new user. For parameter details,
see [Streamlined Linking
Intents](https://developers.google.com/identity/account-linking/your-api-reference#handle_streamlined_linking_intents).

##### Implementation Recipe

To handle the optional `create` intent, perform the following actions:

1. **Validate the request**:

   - Verify `client_id`, `client_secret`, and `grant_type`.
   - Validate the `assertion` (JWT).
2. **Verify user does not exist**:

   - Check if the `sub` or `email` is already in your database.
   - If the user *does* exist: Return HTTP `401 Unauthorized` with `{"error": "linking_error", "login_hint": "USER_EMAIL"}` to force fallback to OAuth linking.
3. **Create account**:

   - Use the `sub`, `email`, `name`, and `picture` claims from the JWT to create a new user record.
4. **Respond**:

   - Generate and return tokens in a JSON response (HTTP `200 OK`).

## Get your Google API Client ID

You will be required to provide your Google API Client ID during the Account
Linking [registration](https://developers.google.com/identity/account-linking/registration) process. To get your API Client ID using
the project you created while completing the
[OAuth linking](https://developers.google.com/identity/account-linking/oauth-linking#create_the_project) steps. To do so, complete
the following steps:

1. Go to the [Clients page](https://console.developers.google.com/auth/clients).
2. Create or select a Google APIs project.

   If your project doesn't have a Client ID for the Web application Type, click
   **Create Client** to create one. Be sure to include your site's domain in
   the **Authorized JavaScript origins** box. When you perform local tests or
   development, you must add both `http://localhost` and
   `http://localhost:<port_number>` to the **Authorized JavaScript origins**
   field.

   > [!IMPORTANT]
   > **Key Point:** Add both `http://localhost` and `http://localhost:<port_number>` to the **Authorized JavaScript origins** field for local tests or development.

   > [!NOTE]
   > **Note:** A Client ID looks like the following example:
   >
   > ```
   > 1234567890-abc123def456.apps.googleusercontent.com
   > ```

## Validate your implementation

You can validate your implementation by using the
[OAuth 2.0 Playground](https://developers.google.com/oauthplayground/) tool.

In the tool, do the following steps:

1. Click **Configuration** to open the OAuth 2.0 Configuration window.
2. In the **OAuth flow** field, select **Client-side**.
3. In the **OAuth Endpoints** field, select **Custom**.
4. Specify your OAuth 2.0 endpoint and the client ID you assigned to Google in the corresponding fields.
5. In the **Step 1** section, don't select any Google scopes. Instead, leave this field blank or type a scope valid for your server (or an arbitrary string if you don't use OAuth scopes). When you're done, click **Authorize
   APIs**.
6. In the **Step 2** and **Step 3** sections, go through the OAuth 2.0 flow and verify that each step works as intended.

You can validate your implementation by using the
[Google Account Linking Demo](https://gal-demo.withgoogle.com) tool.

In the tool, do the following steps:

1. Click the **Sign in with Google** button.
2. Choose the account you'd like to link.
3. Enter the service ID.
4. Optionally enter one or more scopes that you will request access for.
5. Click **Start Demo**.
6. When prompted, confirm that you may consent and deny the linking request.
7. Confirm that you are redirected to your platform.