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',
authorizationParams: {
redirect_uri: window.location.origin,
},
}),
],
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({
logoutParams: {
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',
authorizationParams: {
redirect_uri: 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: {
authorizationParams: {
audience: 'http://my-api/',
scope: 'read:accounts',
}
},
},
// Matching on HTTP method
{
uri: '/api/orders',
httpMethod: 'post',
tokenOptions: {
authorizationParams: {
audience: 'http://my-api/',
scope: 'write:orders',
}
},
},
// Using an absolute URI
{
uri: 'https://your-domain.auth0.com/api/v2/users',
tokenOptions: {
authorizationParams: {
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.