How to Use Refresh Tokens in a SPA

Overview

Using refresh tokens is a common design pattern for Single Page Applications (SPAs) implementing authentication and authorization using Auth0. While relatively straightforward, several steps are required to get an app up and running with refresh tokens.

Applies To
  • Refresh Tokens
  • Single-Page Applications (SPA)
Solution

Step 1: Configure required settings in the Auth0 Dashboard

42b034e6b5361bedfb4d675a003607c2908ddcd3_2_690x341.png
 

  • Confirm the Allowed Callback URLs are properly set to the application’s URL where Auth0 can redirect after authentication.
ccb091fb00ef896da09ba2ea67acc6e068f971cc_2_690x229.png
  • Enable Refresh Token Rotation - Refresh token rotation is a security feature that helps protect against the misuse of refresh tokens. It ensures that refresh tokens are not long-lived and can be rotated (i.e., replaced) frequently, reducing the risk of token theft and unauthorized access.
f39e000969a8edd7861be0c634d15449bf825a02_2_690x149 (1).png
  • Enable Allow Offline Access in the settings of the API registered in Auth0.
1fbdf8a02af91d10df5ffab1e538424699612d12_2_690x306.png

Important to note:

  • Refresh token grant is not available for the Management API. Management API access tokens require a client credentials exchange and should generally not be handled in a public client (SPA). If the use case permits, Management API access tokens can be requested from a frontend, but will be limited in scope.
  • If an audience param is omitted from the authorize request, the returned access token will be opaque. See below on how to include this param in all Auth0 Single-Page Application (SPA) SDK Libraries.

Step 2: Configure the Auth0 SPA SDK of choice

auth0-react

import React from 'react';
import { createRoot } from 'react-dom/client';
import { Auth0Provider } from '@auth0/auth0-react';
import App from './App';

const root = createRoot(document.getElementById('root'));

root.render(
<Auth0Provider
    domain='{yourDomain}'
    clientId='{yourClientId}'
    useRefreshTokens={true}
    authorizationParams={{
      redirect_uri: window.location.origin
      audience: 'https://your_audience'
    }}
  >
    <App />
  </Auth0Provider>,
);

auth0-angular

import { bootstrapApplication } from '@angular/platform-browser';
import { provideAuth0 } from '@auth0/auth0-angular';
import { AppComponent } from './app.component';

bootstrapApplication(AppComponent, {
  providers: [
    provideAuth0({
      domain: '{yourDomain}',
      clientId: '{yourClientId}',
      useRefreshTokens: true,
      authorizationParams: {
        redirect_uri: window.location.origin,
        audience: 'https://your_audience'
      }
    }),
  ]
});

auth0-vue

import { createAuth0 } from '@auth0/auth0-vue';

const app = createApp(App);

app.use(
  createAuth0({
    domain: '<AUTH0_DOMAIN>',
    clientId: '<AUTH0_CLIENT_ID>',
    authorizationParams: {
      redirect_uri: '<MY_CALLBACK_URL>',
      audience: '<AUTH0_AUDIENCE>',
      useRefreshTokens: true
    }
  })
);

app.mount('#app');

auth0-flutter

 Future<void> login() async {
    try {
      if (kIsWeb) {
        return auth0Web.loginWithRedirect(
             redirectUrl: 'http://localhost:3000',
             audience: 'https://your_audience',
             scopes: 'openid, profile, offline_access'
        );
      }

      var credentials = await auth0
          .webAuthentication(scheme: dotenv.env['AUTH0_CUSTOM_SCHEME'])
          // Use a Universal Link callback URL on iOS 17.4+ / macOS 14.4+
          // useHTTPS is ignored on Android
          .login(useHTTPS: true);

      setState(() {
        _user = credentials.user;
      });
    } catch (e) {
      print(e);
    }
  }

auth0-spa-js

await createAuth0Client({
  domain: '<AUTH0_DOMAIN>',
  clientId: '<AUTH0_CLIENT_ID>',
  useRefreshTokens: true,
  authorizationParams: {
    redirect_uri: '<MY_CALLBACK_URL>',
    audience: 'https://your_audience'
  }
});

Logging

Successful refresh token exchanges will be logged under the event type code sertft - More on Auth0 dashboard logging here.

Additional Useful Material:

  • What are Refresh Tokens?! and…How to Use Them Securely (Video)
  • Auth0 SPA SDK Quickstarts





 

Recommended content

No recommended content found...