ID Token

Overview

The ID token, usually referred to in our docs as id_token, is a JSON Web Token (JWT) that contains user profile information (like the user's name, email, and so forth), represented in the form of claims. These claims are statements about the user, which can be trusted if the consumer of the token can verify its signature.

Υou must verify the ID token's signature before storing and using it.

You will need to decode this token to read the claims (or attributes) of the user. The JWT website provides a list of libraries you can use to decode the id_token.

The id_token is consumed by the client and the claims included, are typically used for UI display. It was added to the OIDC specification as an optimization so the client can know the identity of the user, without having to make an additional network requests.

If you need a refresher on OIDC refer to OpenID Connect.

The id_token conforms to an industry standard (IETF RFC 7519) and contains three parts: a header, a body and a signature.

  • The header contains the type of token and the hash algorithm used on the contents of the token.

  • The body, also called the payload, contains identity claims about a user. There are some claims with registered names, for things like the issuer of the token, the subject of the token (who the claims are about), and the time of issuance. Any number of additional claims with other names can be added. For the cases where the id_token is returned in URLs, care must be taken to keep the JWT within the browser size limitations for URLs.

  • The signature is used by the recipient to verify that the sender of the JWT is who it says and to ensure that the message wasn't changed along the way.

Get an ID token

The id_token can be returned when calling any of the Auth0 functions which invoke authentication. This includes calls to the Lock widget, to the auth0.js library, the Authentication API, or the libraries for other languages. You can view the implementation details for retrieving the id_token at the Lock web library and Auth0.js library documents.

Validate an ID token

In order to validate an id_token, an application needs to verify the signature of the token, as well as validate the standard claims of the token. Each of these steps are discussed in more detail below.

Most JWT libraries will take care of the token validation for you automatically, so be sure to reference the Libraries for Token Signing/Verification section of JWT.io to find a JWT library for your platform and programming language.

Verify the signature

The signature is used to verify that the sender of the token is who it says it is and to ensure that the message wasn't changed along the way.

Remember that the id_token is always a JWT, and the signature is created using its header and payload, a secret and the hashing algorithm being used (as specified in the header: HMAC, SHA256 or RSA). The way to verify it, depends on the hashing algorithm:

  • For HS256, the API's Signing Secret is used. You can find this information at your API's Settings. Note that the field is only displayed for APIs that use HS256.
  • For RS256, the tenant's JSON Web Key Set (JWKS) is used. Your tenant's JWKS is https://YOUR_AUTH0_DOMAIN/.well-known/jwks.json.

The most secure practice, and our recommendation, is to use RS256.

To check or update the algorithm your Client uses go to Client Settings > Show Advanced Settings > OAuth > JsonWebToken Signature Algorithm.

Validate the Claims

Once the application verifies the token's signature, the next step is to validate the standard claims of the token's payload. The following validations need to be made:

  • Token expiration: The current date/time must be before the expiration date/time listed in the exp claim (which is a Unix timestamp).

  • Token issuer: The iss claim denotes the issuer of the JWT. The value must match the the URL of your Auth0 tenant. For JWTs issued by Auth0, iss holds your Auth0 domain with a https:// prefix and a / suffix: https://YOUR_AUTH0_DOMAIN/.

  • Token audience: The aud claim identifies the recipients that the JWT is intended for. The value must match the Client ID of your Auth0 Client.

Control the contents of an ID token

In order to retrieve an id_token the responseType should include the id_token, both for client-side and server-side authentication flows.

The attributes included in the issued id_token are controlled by the use of a parameter called scope.

  • If scope is set to openid, then the id_token will contain only the iss, sub, aud, exp and iat claims.
  • If scope is set to openid email, then the id_token will contain additionally the email and email_verified claims.
  • If scope is set to openid profile, then the id_token will contain all default profile Claims, which are: name, family_name, given_name, middle_name, nickname, preferred_username, profile, picture, website, gender, birthdate, zoneinfo, locale, and updated_at.

If you are using Lock, the options object used in Lock’s instantiation can specify optional authentication parameters as follows:

var options = {
  auth: {
    responseType: 'id_token',
    params: {scope: 'openid email'}
  }
};

var lock = new Auth0Lock(
  YOUR_CLIENT_ID,
  YOUR_AUTH0_DOMAIN,
  options
);

lock.show();

The id_token will contain only the claims specified as the value of the scope parameter.

Add Custom Claims

You can add custom claims to your ID token (or Access Token) using Rules.

The claim name must conform to a namespaced format, which basically means addind any non-Auth0 HTTP or HTTPS URL as a prefix. The Auth0 namespaces you cannot use are auth0.com, webtask.io and webtask.run. The format you should follow is this: http://my-namespace/claim-name.

For more information on the namespaced format of custom claims, refer to User profile claims and scope.

For an example of how to add a custom claim, refer to Add Custom Claims.

ID Token Payload

The JWT.io website has a debugger that allows you to debug any JSON Web Token. This is useful if you want to quckly decode a JWT to see the information it contains.

The payload's claims can include some or all of the following:

Parameter Description
name The name of the user which is returned from the Identity Provider.
email The email address of the user which is returned from the Identity Provider.
picture The profile picture of the user which is returned from the Identity Provider.
sub The unique identifier of the user. This is guaranteed to be unique per user and will be in the format (identity provider)|(unique id in the provider), e.g. github|1234567890.
iss The issuer. A case-sensitive string or URI that uniquely identifies the party that issued the JWT. For an Auth0 issued id_token, this will be the URL of your Auth0 tenant.

This is a registered claim according to the JWT Specification
aud The audience. Either a single case-sensitive string or URI or an array of such values that uniquely identify the intended recipients of this JWT. For an Auth0 issued id_token, this will be the Client ID of your Auth0 Client.

This is a registered claim according to the JWT Specification
exp The expiration time. A number representing a specific date and time in the format “seconds since epoch” as defined by POSIX6. This claim sets the exact moment from which this JWT is considered invalid.

This is a registered claim according to the JWT Specification
iat The issued at time. A number representing a specific date and time (in the same format as exp) at which this JWT was issued.

This is a registered claim according to the JWT Specification

The exact claims contained in the id_token will depend on the scope parameter you sent to the /authorize endpoint. An Auth0 id_token will always include the registered claims and the sub claim, but the others depends on the scope.

Token Lifetime

The purpose of the id_token is to cache user information for better performance and experience, and by default, the token is valid for 36000 seconds, or 10 hours. You may change this setting as you see fit; if there are security concerns, you may certainly shorten the time period before the token expires, but remember that the id_token helps ensure optimal performance by reducing the need to contact the Identity Provider every time the user performs an action that requires an API call.

The expiration time can be changed in the Dashboard > Clients > Settings screen using the JWT Expiration (seconds) field.

There are cases where you might want to renew your id_token. In order to do so, you can either perform another authorization flow with Auth0 (using the /authorize endpoint) or use a Refresh Token.

When performing the initial authorization flow, you can ask for a refresh_token, by adding offline_access at the scope parameter, for example scope=openid offline_access. The refresh_token is stored in session, alongside with the id_token. Then when a session needs to be refreshed (for example, a preconfigured timeframe has passed or the user tries to perform a sensitive operation), the app uses the refresh_token on the backend to obtain a new id_token, using the /oauth/token endpoint with grant_type=refresh_token.

This method is not an option for Single Page Apps (SPAs), since for security reasons you cannot get a refresh_token from the Implicit Grant (the OAuth flow typically used from Client-side Web Apps). In that case you would have to use silent authentication.

If you are using auth0.js on an SPA, then you can fetch a new token using the renewAuth() method.

auth0.renewAuth({
  audience: 'https://mystore.com/api/v2',
  scope: 'read:order write:order',
  redirectUri: 'https://example.com/auth/silent-callback',

  // this will use postMessage to comunicate between the silent callback
  // and the SPA. When false the SDK will attempt to parse the url hash
  // should ignore the url hash and no extra behaviour is needed.
  usePostMessage: true
  }, function (err, authResult) {
    // Renewed tokens or error
});

Revoke access

Once issued, tokens can not be revoked in the same fashion as cookies with session id’s for server-side sessions. As a result, tokens should be issued for relatively short periods, and then renewed periodically if the user remains active.

Keep Reading