# Authenticate with a backend server

[Video](https://www.youtube.com/watch?v=j_31hJtWjlw)

If you use Google Sign-In with an app or site that communicates with a backend
server, you might need to identify the currently signed-in user on the server.
To do so securely, after a user successfully signs in, send the user's
ID token to your server using HTTPS. Then, on the server, verify the integrity
of the ID token and use the user information contained in the token to establish
a session or create a new account.

> [!WARNING]
> **Warning:** Do not accept plain user IDs, such as those you can get with the `` `GoogleUser.getId()` method ``, on your backend server. A modified client application can send arbitrary user IDs to your server to impersonate users, so you must instead use verifiable ID tokens to securely get the user IDs of signed-in users on the server side.

## Send the ID token to your server

After a user successfully signs in, get the user's ID token:

```
function onSignIn(googleUser) {
  var id_token = googleUser.getAuthResponse().id_token;
  ...
}
```

Then, send the ID token to your server with an HTTPS POST request:

```
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://yourbackend.example.com/tokensignin');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onload = function() {
  console.log('Signed in as: ' + xhr.responseText);
};
xhr.send('idtoken=' + id_token);
```

## Verify the integrity of the ID token

After you receive the ID token by HTTPS POST, you must verify the integrity
of the token.

To verify that the token is valid, ensure that the following
criteria are satisfied:

- The ID token is properly signed by Google. Use Google's public keys (available in [JWK](https://www.googleapis.com/oauth2/v3/certs) or [PEM](https://www.googleapis.com/oauth2/v1/certs) format) to verify the token's signature. These keys are regularly rotated; examine the `Cache-Control` header in the response to determine when you should retrieve them again.
- The value of `aud` in the ID token is equal to one of your app's client IDs. This check is necessary to prevent ID tokens issued to a malicious app being used to access data about the same user on your app's backend server.
- The value of `iss` in the ID token is equal to `accounts.google.com` or `https://accounts.google.com`.
- The expiry time (`exp`) of the ID token has not passed.
- If you need to validate that the ID token represents a Google Workspace or Cloud organization account, you can check the `hd` claim, which indicates the hosted domain of the user. This must be used when restricting access to a resource to only members of certain domains. The absence of this claim indicates that the account does not belong to a Google hosted domain.


Using the `email`, `email_verified` and `hd` fields, you can determine if
Google hosts and is authoritative for an email address. In the cases where Google is authoritative,
the user is known to be the legitimate account owner, and you may skip password or other
challenge methods.


Cases where Google is authoritative:

- `email` has a `@gmail.com` suffix, this is a Gmail account.
- `email_verified` is true and `hd` is set, this is a Google Workspace account.

<br />


Users may register for Google Accounts without using Gmail or Google Workspace. When
`email` does not contain a `@gmail.com` suffix and `hd` is absent, Google is not
authoritative and password or other challenge methods are recommended to verify
the user. `email_verified` can also be true as Google initially verified the
user when the Google account was created, however ownership of the third party
email account may have since changed.

Rather than writing your own code to perform these verification steps, we strongly
recommend using a Google API client library for your platform, or a general-purpose
JWT library. For development and debugging, you can call our `tokeninfo`
validation endpoint.

### Using a Google API Client Library

Using one of the [Google API Client Libraries](https://developers.google.com/api-client-library) (e.g.
[Java](https://github.com/googleapis/google-auth-library-java),
[Node.js](https://github.com/google/google-api-nodejs-client),
[PHP](https://developers.google.com/api-client-library/php/start/get_started),
[Python](https://google-auth.readthedocs.io/))
is the recommended way to validate Google ID tokens in a production environment.
Java

To validate an ID token in Java, use the [GoogleIdTokenVerifier](https://github.com/googleapis/google-api-java-client/blob/master/google-api-client/src/main/java/com/google/api/client/googleapis/auth/oauth2/GoogleIdTokenVerifier.java) object. For example:

```java
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;

...

GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
    // Specify the WEB_CLIENT_ID of the app that accesses the backend:
    .setAudience(Collections.singletonList(WEB_CLIENT_ID))
    // Or, if multiple clients access the backend:
    //.setAudience(Arrays.asList(WEB_CLIENT_ID_1, WEB_CLIENT_ID_2, WEB_CLIENT_ID_3))
    .build();

// (Receive idTokenString by HTTPS POST)

GoogleIdToken idToken = verifier.verify(idTokenString);
if (idToken != null) {
  Payload payload = idToken.getPayload();

  // Print user identifier. This ID is unique to each Google Account, making it suitable for
  // use as a primary key during account lookup. Email is not a good choice because it can be
  // changed by the user.
  String userId = payload.getSubject();
  System.out.println("User ID: " + userId);

  // Get profile information from payload
  String email = payload.getEmail();
  boolean emailVerified = Boolean.valueOf(payload.getEmailVerified());
  String name = (String) payload.get("name");
  String pictureUrl = (String) payload.get("picture");
  String locale = (String) payload.get("locale");
  String familyName = (String) payload.get("family_name");
  String givenName = (String) payload.get("given_name");

  // Use or store profile information
  // ...

} else {
  System.out.println("Invalid ID token.");
}
```

The `GoogleIdTokenVerifier.verify()` method verifies the JWT
signature, the `aud` claim, the `iss` claim, and the
`exp` claim.

If you need to validate that the ID token represents a Google Workspace or Cloud
organization account, you can verify the `hd` claim by checking the domain name
returned by the `Payload.getHostedDomain()` method. The domain of the
`email` claim is insufficient to ensure that the account is managed by a domain
or organization.
Node.js

To validate an ID token in Node.js, use the [Google Auth Library for Node.js](https://github.com/google/google-auth-library-nodejs).
Install the library:

```
npm install google-auth-library --save
```
Then, call the `verifyIdToken()` function. For example:

<br />

```javascript
const {OAuth2Client} = require('google-auth-library');
const client = new OAuth2Client();
async function verify() {
  const ticket = await client.verifyIdToken({
      idToken: token,
      audience: WEB_CLIENT_ID,  // Specify the WEB_CLIENT_ID of the app that accesses the backend
      // Or, if multiple clients access the backend:
      //[WEB_CLIENT_ID_1, WEB_CLIENT_ID_2, WEB_CLIENT_ID_3]
  });
  const payload = ticket.getPayload();
  // This ID is unique to each Google Account, making it suitable for use as a primary key
  // during account lookup. Email is not a good choice because it can be changed by the user.
  const userid = payload['sub'];
  // If the request specified a Google Workspace domain:
  // const domain = payload['hd'];
}
verify().catch(console.error);
```

The `verifyIdToken` function verifies
the JWT signature, the `aud` claim, the `exp` claim,
and the `iss` claim.

If you need to validate that the ID token represents a Google Workspace or Cloud
organization account, you can check the `hd` claim, which indicates the hosted
domain of the user. This must be used when restricting access to a resource to only members
of certain domains. The absence of this claim indicates that the account does not belong to
a Google hosted domain.
PHP

To validate an ID token in PHP, use the [Google API Client Library for PHP](https://github.com/google/google-api-php-client/).
Install the library (for example, using Composer):

```
composer require google/apiclient
```
Then, call the `verifyIdToken()` function. For example:

<br />

```php
require_once 'vendor/autoload.php';

// Get $id_token via HTTPS POST.

$client = new Google_Client(['client_id' => $WEB_CLIENT_ID]);  // Specify the WEB_CLIENT_ID of the app that accesses the backend
$payload = $client->verifyIdToken($id_token);
if ($payload) {
  // This ID is unique to each Google Account, making it suitable for use as a primary key
  // during account lookup. Email is not a good choice because it can be changed by the user.
  $userid = $payload['sub'];
  // If the request specified a Google Workspace domain
  //$domain = $payload['hd'];
} else {
  // Invalid ID token
}
```

The `verifyIdToken` function verifies
the JWT signature, the `aud` claim, the `exp` claim,
and the `iss` claim.

If you need to validate that the ID token represents a Google Workspace or Cloud
organization account, you can check the `hd` claim, which indicates the hosted
domain of the user. This must be used when restricting access to a resource to only members
of certain domains. The absence of this claim indicates that the account does not belong to
a Google hosted domain.
Python

To validate an ID token in Python, use the
[verify_oauth2_token](https://google-auth.readthedocs.io/en/latest/reference/google.oauth2.id_token.html#google.oauth2.id_token.verify_oauth2_token)
function. For example:

```python
from google.oauth2 import id_token
from google.auth.transport import requests

# (Receive token by HTTPS POST)
# ...

try:
    # Specify the WEB_CLIENT_ID of the app that accesses the backend:
    idinfo = id_token.verify_oauth2_token(token, requests.Request(), WEB_CLIENT_ID)

    # Or, if multiple clients access the backend server:
    # idinfo = id_token.verify_oauth2_token(token, requests.Request())
    # if idinfo['aud'] not in [WEB_CLIENT_ID_1, WEB_CLIENT_ID_2, WEB_CLIENT_ID_3]:
    #     raise ValueError('Could not verify audience.')

    # If the request specified a Google Workspace domain
    # if idinfo['hd'] != DOMAIN_NAME:
    #     raise ValueError('Wrong domain name.')

    # ID token is valid. Get the user's Google Account ID from the decoded token.
    # This ID is unique to each Google Account, making it suitable for use as a primary key
    # during account lookup. Email is not a good choice because it can be changed by the user.
    userid = idinfo['sub']
except ValueError:
    # Invalid token
    pass
```

The `verify_oauth2_token` function verifies the JWT
signature, the `aud` claim, and the `exp` claim.
You must also verify the `hd`
claim (if applicable) by examining the object that
`verify_oauth2_token` returns. If multiple clients access the
backend server, also manually verify the `aud` claim.

### Calling the tokeninfo endpoint

An easy way to validate an ID token signature for *debugging* is to
use the `tokeninfo` endpoint. Calling this endpoint involves an
additional network request that does most of the validation for you while you test proper
validation and payload extraction in your own code. It is not suitable for use in production
code as requests may be throttled or otherwise subject to intermittent errors.

To validate an ID token using the `tokeninfo` endpoint, make an HTTPS
POST or GET request to the endpoint, and pass your ID token in the
`id_token` parameter.
For example, to validate the token "XYZ123", make the following GET request:

```
https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123
```

If the token is properly signed and the `iss` and `exp`
claims have the expected values, you will get a HTTP 200 response, where the body
contains the JSON-formatted ID token claims.
Here's an example response:

```
{
 // These six fields are included in all Google ID Tokens.
 "iss": "https://accounts.google.com",
 "sub": "110169484474386276334",
 "azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "iat": "1433978353",
 "exp": "1433981953",

 // These seven fields are only included when the user has granted the "profile" and
 // "email" OAuth scopes to the application.
 "email": "testuser@gmail.com",
 "email_verified": "true",
 "name" : "Test User",
 "picture": "https://lh4.googleusercontent.com/-kYgzyAWpZzJ/ABCDEFGHI/AAAJKLMNOP/tIXL9Ir44LE/s99-c/photo.jpg",
 "given_name": "Test",
 "family_name": "User",
 "locale": "en"
}
```

> [!WARNING]
> **Warning:** Once you get these claims, you still need to check that the `aud` claim contains one of your app's client IDs. If it does, then the token is both valid and intended for your client, and you can safely retrieve and use the user's unique Google ID from the `sub` claim.

If you need to validate that the ID token represents a Google Workspace account, you can check
the `hd` claim, which indicates the hosted domain of the user. This must be used when
restricting access to a resource to only members of certain domains. The absence of this claim
indicates that the account does not belong to a Google Workspace hosted domain.

## Create an account or session

After you have verified the token, check if the user is already in your user
database. If so, establish an authenticated session for the user. If the user
isn't yet in your user database, create a new user record from the information
in the ID token payload, and establish a session for the user. You can prompt
the user for any additional profile information you require when you detect a
newly created user in your app.

## Securing your users' accounts with Cross Account Protection

When you rely on Google to sign in a user, you'll automatically benefit from all of the
security features and infrastructure Google has built to safeguard the user's data. However,
in the unlikely event that the user's Google Account gets compromised or there is some other
significant security event, your app can also be vulnerable to attack. To better protect your
accounts from any major security events, use [Cross Account
Protection](https://developers.google.com/identity/protocols/risc) to receive security alerts from Google. When you receive these events, you
gain visibility into important changes to the security of the user's Google account and
you can then take action on your service to secure your accounts.