Auth0 Single Page App SDK

Auth0 Single Page App SDK

The Auth0 Single Page App SDK is a new JavaScript library for implementing authentication and authorization in single page apps (SPA) with Auth0. It provides a high-level API and handles a lot of the details so you can secure SPAs using best practices while writing less code.

The Auth0 SPA SDK handles grant and protocol details, token expiration and renewal, as well as token storage and caching. Under the hood, it implements Universal Login and the Authorization Code Grant Flow with PKCE.

The library and API documentation are hosted on GitHub.

If you encounter any problems or errors when using the new JavaScript SDK, please read the FAQ to see if your issue is covered there.

Installation

You have a few options for using the Auth0 SPA SDK in your project:

  • From the CDN: <script src="https://cdn.auth0.com/js/auth0-spa-js/2.0/auth0-spa-js.production.js"></script>

  • With npm: npm install @auth0/auth0-spa-js

  • With yarn: yarn add @auth0/auth0-spa-js

Getting Started

Create the client

First, you'll need to create a new instance of Auth0Client client object. Create the Auth0Client instance before rendering or initializing your application. You can do this using either the async/await method, or with promises. You should only create one instance of the client.

Using createAuth0Client does a couple of things automatically:

  • It creates an instance of Auth0Client.

  • It calls getTokenSilently to refresh the user session.

  • It suppresses all errors from getTokenSilently, except login_required.

Use async/await

import { createAuth0Client } from '@auth0/auth0-spa-js';

const auth0 = await createAuth0Client({
  domain: 'YOUR_DOMAIN',
  clientId: 'YOUR_CLIENT_ID'
});

Was this helpful?

/

Use promises

createAuth0Client({
  domain: 'YOUR_DOMAIN',
  clientId: 'YOUR_CLIENT_ID'
}).then(auth0 => {
  //...
});

Was this helpful?

/

You can also create the client directly using the Auth0Client constructor. This can be useful if you want to:

  • Bypass the call to getTokenSilently on initialization.

  • Do custom error handling.

  • Initialize the SDK in a synchronous way.

import { Auth0Client } from '@auth0/auth0-spa-js';

const auth0 = new Auth0Client({
  domain: 'YOUR_DOMAIN',
  clientId: 'YOUR_CLIENT_ID'
});

Was this helpful?

/

Login and get user info

Next, create a button users can click to start logging in:

<button id="login">Click to Login</button>

Listen for click events on the button you created. When the event occurs, use the desired login method to authenticate the user (loginWithRedirect() in this example). After the user is authenticated, you can retrieve the user profile with the getUser() method.

Use async/await

document.getElementById('login').addEventListener('click', async () => {
  await auth0.loginWithRedirect({
    authorizationParams: {
      redirect_uri: 'http://localhost:3000/'
    }
  });
  //logged in. you can get the user profile like this:
  const user = await auth0.getUser();
  console.log(user);
});

Was this helpful?

/

Use promises

document.getElementById('login').addEventListener('click', () => {
  auth0.loginWithRedirect({
    authorizationParams: {
      redirect_uri: 'http://localhost:3000/'
    }
  }).then(token => {
    //logged in. you can get the user profile like this:
    auth0.getUser().then(user => {
      console.log(user);
    });
  });
});

Was this helpful?

/

Call an API

To call your API, start by getting the user's Access Token. Then use the Access Token in your request. In this example, the getTokenSilently method is used to retrieve the Access Token:

<button id="callApi">Call an API</button>

Use async/await

document.getElementById('callApi').addEventListener('click', async () => {
  const accessToken = await auth0.getTokenSilently();
  const result = await fetch('https://exampleco.com/api', {
    method: 'GET',
    headers: {
      Authorization: 'Bearer ' + accessToken
    }
  });
  const data = await result.json();
  console.log(data);
});

Was this helpful?

/

Use promises

document.getElementById('callApi').addEventListener('click', () => {
  auth0
    .getTokenSilently()
    .then(accessToken =>
      fetch('https://exampleco.com/api', {
        method: 'GET',
        headers: {
          Authorization: 'Bearer ' + accessToken
        }
      })
    )
    .then(result => result.json())
    .then(data => {
      console.log(data);
    });
});

Was this helpful?

/

Logout

Add a button users can click to logout:

<button id="logout">Logout</button>

$('#logout').click(async () => {
  auth0.logout({
    logoutParams: {
      returnTo: 'http://localhost:3000/'
    }
  });
});

Was this helpful?

/

Change storage options

The Auth0 SPA SDK stores tokens in memory by default. However, this does not provide persistence across page refreshes and browser tabs. Instead, you can opt-in to store tokens in local storage by setting the cacheLocation property to localstorage when initializing the SDK. This can help to mitigate some of the effects of browser privacy technology that prevents access to the Auth0 session cookie by storing Access Tokens for longer.

const auth0 = await createAuth0Client({
  domain: '{yourDomain}',
  clientId: '{yourClientId}',
  cacheLocation: 'localstorage'
});

Was this helpful?

/

Use rotating Refresh Tokens

The Auth0 SPA SDK can be configured to use rotating Refresh Tokens to get new access tokens silently. These can be used to bypass browser privacy technology that prevents access to the Auth0 session cookie when authenticating silently, as well as providing built-in reuse detection.

Configure the SDK to do this by setting useRefreshTokens to true on initialization:

const auth0 = await createAuth0Client({
  domain: '{yourDomain}',
  clientId: '{yourClientId}',
  useRefreshTokens: true
});

// Request a new access token using a refresh token
const token = await auth0.getTokenSilently();

Was this helpful?

/

Refresh Tokens will also need to be configured for your tenant before they can be used in your SPA.

Once configured, the SDK will request the offline_access scope during the authorization step. Furthermore, getTokenSilently will then call the /oauth/token endpoint directly to exchange refresh tokens for access tokens. The SDK will obey the storage configuration when storing refresh tokens. If the SDK has been configured using the default in-memory storage mechanism, refresh tokens will be lost when refreshing the page.

Usage

Below are examples of usage for various methods in the SDK. Note that jQuery is used in these examples.

Login with redirect

Redirect to the /authorize endpoint at Auth0, starting the Universal Login flow:

$('#loginRedirect').click(async () => {
  await auth0.loginWithRedirect({
    authorizationParams: {
      redirect_uri: 'http://localhost:3000/'
    }
  });
});

Was this helpful?

/

Login with popup

Use a popup window to log in using the Universal Login page:

$('#loginPopup').click(async () => {
  await auth0.loginWithPopup();
});

Was this helpful?

/

If the user takes longer than the default timeout of 60 seconds to complete the authentication flow, the authentication will be interrupted, and you will need to catch the error in your code to either:

Suggest that the user retry and close the popup manually using error.popup.close:

$('#loginPopup').click(async () => {
  try {
    await auth0.loginWithPopup();
  } catch {error}
  if (error instanceof auth0.PopupTimeoutError) {
    // custom logic to inform user to retry
    error.popup.close();
  }
});

Was this helpful?

/

Or create a custom popup option in the options object:

$('#loginPopup').click(async () => {
  const popup = window.open(
    '',
    'auth0:authorize:popup',
    'left=100,top=100,width=400,height=600,resizable'
  );
  try {
    await auth0.loginWithPopup({ popup });
  } catch {error}
  if (error instanceof auth0.PopupTimeoutError) {
    // custom logic to inform user to retry
    error.popup.close();
  }
});

Was this helpful?

/

Login with redirect callback

When the browser is redirected from Auth0 back to your SPA, handleRedirectCallback must be called in order to complete the login flow:

$('#loginRedirectCallback').click(async () => {
  await auth0.handleRedirectCallback();
});

Was this helpful?

/

Get Access Token with no interaction

Get a new Access Token silently using either a hidden iframe and prompt=none, or by using a rotating Refresh Token. Refresh Tokens are used when useRefreshTokens is set to true when configuring the SDK.

If in-memory storage (the default) and refresh tokens are used, new tokens are retrieved using a web worker on supported browsers:

$('#getToken').click(async () => {
  const token = await auth0.getTokenSilently();
});

Was this helpful?

/

The getTokenSilently() method requires you to have Allow Skipping User Consent enabled in your API Settings in the Dashboard. Additionally, user consent cannot be skipped on 'localhost'.

Get Access Token with popup

Access Tokens can also be retrieved using a popup window. Unlike getTokenSilently, this method of retrieving an Access Token will work in browsers where third-party cookies are blocked by default:

$('#getTokenPopup').click(async () => {
  const token = await auth0.getTokenWithPopup({
    authorizationParams: {
      audience: 'https://mydomain/api/',
      scope: 'read:rules'
    }
  });
});

Was this helpful?

/

Get Access Token for a different audience

Options may be passed to getTokenSilently that get an Access Token with a different audience and scope of that which was requested at user authentication time.

$('#getToken_audience').click(async () => {
  const differentAudienceOptions = {
    authorizationParams: {
      audience: 'https://mydomain/another-api/',
      scope: 'read:rules',
      redirect_uri: 'http://localhost:3000/callback.html'
    }
  };
  const token = await auth0.getTokenSilently(differentAudienceOptions);
});

Was this helpful?

/

Get user

You can get the authenticated user's profile data by calling the getUser method:

$('#getUser').click(async () => {
  const user = await auth0.getUser();
});

Was this helpful?

/

Get ID Token claims

You can get the claims of the authenticated user's ID Token by calling the getIdTokenClaims method:

$('#getIdTokenClaims').click(async () => {
  const claims = await auth0.getIdTokenClaims();
  // if you need the raw id_token, you can access it
  // using the __raw property
  const id_token = claims.__raw;
});

Was this helpful?

/

Logout (default)

You can initiate a logout action by calling the logout method:

$('#logout').click(async () => {
  auth0.logout({
    logoutParams: {
      returnTo: 'http://localhost:3000/'
    }
  });
});

Was this helpful?

/

Logout with no client ID

You can initiate a logout action with no Client ID specified by calling the logout method and including clientId: null:

$('#logoutNoClientId').click(async () => {
  auth0.logout({
    clientId: null,
    logoutParams: {
      returnTo: 'http://localhost:3000/'
    }
  });
});

Was this helpful?

/

Learn more