Auth0 Angular SDK for Single Page Apps

Auth0 Angular SDK for Single Page Apps

The Auth0 Angular SDK is a JavaScript library for implementing authentication and authorization in Angular apps with Auth0. It provides a service, authentication guard, and an HTTP interceptor to enable you to perform common authentication tasks within your Angular apps.

The Auth0 Angular 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 is hosted on GitHub where you can read more about the API.

Installation

Use the Angular CLI to install the SDK into your project:

ng add @auth0/auth0-angular

Getting started

Begin integrating the SDK by importing AuthModule into your project and configuring it for your Auth0 client app:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';

// Import the module from the SDK
import { AuthModule } from '@auth0/auth0-angular';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,

    // Import the module into the application, with configuration
    AuthModule.forRoot({
      domain: 'YOUR_AUTH0_DOMAIN',
      clientId: 'YOUR_AUTH0_CLIENT_ID',
    }),
  ],

  bootstrap: [AppComponent],
})
export class AppModule {}

Was this helpful?

/

Login

The SDK fully supports Angular's dependency injection system. To begin, import the AuthService type into a component and inject it into the constructor.

Then, to initiate user login, call the loginWithRedirect or loginWithPopup methods on the service:

import { Component } from '@angular/core';

// Import the AuthService type from the SDK
import { AuthService } from '@auth0/auth0-angular';

@Component({
  selector: 'app-login',
  template: '<button (click)="login">Log in</button>',
  styles: [],
})
export class LoginComponent {
  // Inject the authentication service into your component through the constructor
  constructor(public auth: AuthService) {}

  login(): void {
    // Call this to redirect the user to the login page
    this.auth.loginWithRedirect();
  }
}

Was this helpful?

/

Logout

Use logout to log your users out. Make sure returnTo is specified in Allowed Logout URLs in your Auth0 Dashboard.

import { Component } from '@angular/core';

// Import the AuthService type from the SDK
import { AuthService } from '@auth0/auth0-angular';

@Component({
  selector: 'app-logout',
  template: '<button (click)="logout">Log out</button>',
  styles: [],
})
export class LogoutComponent {
  // Inject the authentication service into your component through the constructor
  constructor(@Inject(DOCUMENT) private doc: Document, public auth: AuthService) {}

  login(): void {
    // Call this to redirect the user to the login page
    this.auth.logout({ returnTo: this.doc.location.origin });
  }
}

Was this helpful?

/

Authentication State

The authentication state is exposed through the isAuthenticated$ observable:

<div *ngIf="auth.isAuthenticated$ | async">
  <app-login></app-login>
</div>

Was this helpful?

/

User Profile

The user profile for the authenticated user is exposed through the user$ observable:

<ul *ngIf="auth.user$ | async as user">
  <li>{{ user.name }}</li>
  <li>{{ user.email }}</li>
</ul>

Was this helpful?

/

Internally, this observable is chained from the isAuthenticated$ observable, so there is no need to manually check if the user is logged in. It will begin emitting values once an authenticated user is available.

Protect a route

Protect a route component using the built-in AuthGuard. Visits to this route when unauthenticated will redirect the user to the login page and back to this page after login.

The authentication guard should be added to a route definition using the canActivate hook (or canActivateChild if using child routes):

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './unprotected/unprotected.component';
import { ProtectedComponent } from './protected/protected.component';

// Import the authentication guard
import { AuthGuard } from '@auth0/auth0-angular';

const routes: Routes = [
  {
    path: 'protected',
    component: ProtectedComponent,

    // Protect a route by registering the auth guard in the `canActivate` hook
    canActivate: [AuthGuard],
  },
  {
    path: '',
    component: HomeComponent,
    pathMatch: 'full',
  },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}

Was this helpful?

/

The authentication guard also supports the canLoad hook for preventing lazy-loaded modules from being loaded when the user is unauthenticated.

Call an API

The SDK contains a built-in HttpInterceptor that automatically attaches access tokens by injecting an Authorization header when requests are made using Angular's HttpClient service.

You must configure the SDK to specify which routes to the API should have this header automatically added, to prevent access token leakage to recipients that you did not expect.

Import the HTTP interceptor

To start, import the types that you will need in order to integrate the Auth0 HTTP interceptor into your app:

// Import the interceptor module and the Angular types you'll need
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { AuthHttpInterceptor } from '@auth0/auth0-angular';

// Register the interceptor with your app module in the `providers` array
@NgModule({
  declarations: [],
  imports: [
    BrowserModule,
    HttpClientModule,     // Register this so that you can make API calls using HttpClient
    AppRoutingModule,
    AuthModule.forRoot(...),
  ],
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: AuthHttpInterceptor, multi: true },
  ],
  bootstrap: [AppComponent],
})

Was this helpful?

/

Note: The interceptor must be manually registered with your app module (as opposed to automatically registering it) as it is designed to be chained with other interceptors, and we cannot guarantee we will insert it into the right place.

Configure the HTTP interceptor

There are a variety of ways to configure this depending on your needs. A route can be specified using a string, an object with options that influence the token being sent, and can also be matched depending on the HTTP verb being used. Route URIs can also include a wildcard to specify a group of routes.

Note: If an HTTP call is made but does not match a route specified in the configuration, the interceptor will be bypassed and the Authorization header will not be included.

This example shows common ways to tell the SDK which routes should have an Authorization header:

// Modify your existing SDK configuration to include the httpInterceptor config
AuthModule.forRoot({
  domain: 'YOUR_AUTH0_DOMAIN',
  clientId: 'YOUR_AUTH0_CLIENT_ID',
  redirectUri: window.location.origin,

  // The AuthHttpInterceptor configuration
  httpInterceptor: {
    allowedList: [
      // Attach access tokens to any calls to '/api' (exact match)
      '/api',

      // Attach access tokens to any calls that start with '/api/'
      '/api/*',

      // Match anything starting with /api/accounts, but also specify the audience and scope the attached
      // access token must have
      {
        uri: '/api/accounts/*',
        tokenOptions: {
          audience: 'http://my-api/',
          scope: 'read:accounts',
        },
      },

      // Matching on HTTP method
      {
        uri: '/api/orders',
        httpMethod: 'post',
        tokenOptions: {
          audience: 'http://my-api/',
          scope: 'write:orders',
        },
      },

      // Using an absolute URI
      {
        uri: 'https://your-domain.auth0.com/api/v2/users',
        tokenOptions: {
          audience: 'https://your-domain.com/api/v2/',
          scope: 'read:users',
        },
      },
    ],
  },
});

Was this helpful?

/

Note: tokenOptions is passed directly to the getTokenSilently method on the underlying SPA SDK. Please see the documentation for more detail on the properties that are accepted.

Call an API

Make your API call using Angular's HttpClient service. Access tokens should automatically be included via the Authorization header for routes that match the configuration.

export class MyComponent {
  constructor(private http: HttpClient) {}

  callApi(): void {
    this.http.get('/api').subscribe(result => console.log(result));
  }
}

Was this helpful?

/

Note that there is nothing additional required at the call site to provide tokens or other authorization queues; that is all handled by the interceptor and the module configuration.