Docs

Angular: Calling an API

View on Github

Angular: Calling an API

This tutorial demonstrates how to call a backend API using an access token. We recommend you to Log in to follow this quickstart with examples configured for your account.

I want to explore a sample app

2 minutes

Get a sample configured with your account settings or check it out on Github.

View on Github
System requirements: Angular 7+

Most single-page apps use resources from data APIs. You may want to restrict access to those resources, so that only authenticated users with sufficient privileges can access them. Auth0 lets you manage access to these resources using API Authorization.

This tutorial shows you how to create a simple API using Express that serves resources protected by a middleware that looks for and validates access tokens. You will then see how to call this API using an access token granted by the Auth0 authorization server.

If you have been following part 1 of this tutorial, then the following steps can be completed within the same project.

Installation

Create an API

In the APIs section of the Auth0 dashboard, click Create API. Provide a name and an identifier for your API. You will use the identifier later when you're configuring your Javascript Auth0 application instance. For Signing Algorithm, select RS256.

Create API

Getting Started

Create the Backend API

For this example, you'll create an Express server that acts as the backend API. This API will expose an endpoint to validate incoming ID Tokens before returning a response.

Start by installing the following packages:

  • express - a lightweight web server for Node
  • express-jwt - middleware to validate JsonWebTokens
  • jwks-rsa - retrieves RSA signing keys from a JWKS endpoint
  • npm-run-all - a helper to run the SPA and backend API concurrently

Next, create a new file server.js with the following code:

The above API has one available endpoint, /api/external, that returns a JSON response to the caller. This endpoint uses the checkJwt middleware to validate the supplied bearer token using your tenant's JSON Web Key Set. If the token is valid, the request is allowed to continue. Otherwise, the server returns a 401 Unauthorized response.

If you are not logged in when viewing this tutorial, the sample above will show the domain and audience values as "YOUR_TENANT" and "YOUR_API_IDENTIFIER" respectively. These should be replaced with the values from your Auth0 application.

Finally, modify package.json to add two new scripts: dev and server. Running the dev script will now start both the backend server and the serve the Angular application at the same time:

To start the project for this sample, run the dev script from the terminal:

This will start both the backend API and the frontend application together.

Create the client

Proxy to Backend API

In this example, the Node backend and Angular app run on two different ports. In order to call the API from the Angular application, the development server must be configured to proxy requests through to the backend API. This is so that the Angular app can make a request to /api/external and it will be correctly proxied through to the backend API at http://localhost:3001/api/external.

To do this, create a proxy.conf.json file in the root of the project and add the following code:

Now open angular.json and add a reference to the proxy config. In the serve node, include the following reference to the proxy config file:

In order for these changes to take effect, you will need to stop and restart the run script.

Login and Get User Info

Update the Authentication Service

We'll now make several updates in the src/app/auth.service.ts file.

Call an API

Add Audience

First, add the audience value to the creation of the Auth0 client instance:

This setting tells the authorization server that your application would like to call the API with the identifier YOUR_API_IDENTIFIER on the user's behalf. This will cause the authorization server to prompt the user for consent the next time they log in. It will also return an access token that can be used to call the API.

Logout

Manage Access Token

We'll define an observable method to retrieve the access token and make it available for use in our application. Add the following to the AuthService class:

If you'd like to pass options to getTokenSilently when calling the method, you can do so.

Why isn't the token stored in browser storage? Historically, it was common to store tokens in local or session storage. However, browser storage is not a secure place to store sensitive data. The auth0-spa-js SDK manages session retrieval for you so that you no longer need to store sensitive data in browser storage in order to restore sessions after refreshing a Single Page Application.

With auth0-spa-js, we can simply request the token from the SDK when we need it (e.g., in an HTTP interceptor) rather than storing it locally in the Angular app or browser. The SDK manages token freshness as well, so we don't need to worry about renewing tokens when they expire.

Usage

Create an HTTP Interceptor

In order to add the access token to the header of secured API requests, we'll create an HTTP interceptor. Interceptors intercept and handle or modify HTTP requests or responses. Interceptors in Angular are services.

Create an interceptor service with the following CLI command:

Open the generated src/app/interceptor.service.ts file and add the following code:

The AuthService is provided so that we can access the getTokenSilently$() stream. Using this stream in the interceptor ensures that requests wait for the access token to be available before firing.

The intercept() method returns an observable of an HTTP event. In it, we do the following:

  • mergeMap ensures that any new requests coming through don't cancel previous requests that may not have completed yet; this is useful if you have multiple HTTP requests on the same page
  • clone the outgoing request and attach the Authorization header with access token, then send the cloned, authorized request on its way

In order to put the interceptor to work in the application, open the src/app/app-routing.module.ts routing module and add:

In the providers array, we're providing the HTTP_INTERCEPTORS injection token and our InterceptorService class. We then set multi: true because we could potentially use multiple interceptors (which would be called in the order provided).

The interceptor will now run on every outgoing HTTP request. If you have public endpoints as well as protected endpoints, you could use conditional logic in the interceptor to only add the token to requests that require it.

Login with Popup

Call the API

Now we're ready to call the secure API endpoint and display its results in the application. To make HTTP requests in our application, we'll first add the HttpClientModule to the src/app/app.module.ts:

The HttpClientModule must be imported and then added to the NgModule's imports array.

Next, create an API service using the Angular CLI:

Open the generated src/app/api.service.ts file and add:

This creates a ping$() method that returns an observable of the HTTP GET request to the API. This can now be used in the application to call the api/external endpoint.

Now we need somewhere to call the API and display the results. Create a new page component:

Open src/app/external-api/external-api.component.ts and add this code:

The API service is provided and a named subscription to api.ping$() is created. The act of subscribing fires off the HTTP call, which we'll do on a button click in the UI. When data comes back from the API, the results are set in a local property (responseJson).

We do not need to unsubscribe from the api.ping$() observable because it completes once the HTTP request is finished.

Open src/app/external-api/external-api.component.html and replace its contents with the following:

Clicking the button calls the API. The response is displayed in the pre element, which only renders if responseJson is present.

This route now needs to be added to our application. Open src/app/app-routing.module.ts and add the /external-api route like so:

The /external-api route is also guarded with AuthGuard since it requires an authenticated user with an access token.

Finally, add a link to the navigation bar. Open src/app/navbar/navbar.component.html and add:

If, at any time, the application isn't working as expected, the Angular CLI server may need to be restarted. Enter Ctrl+C in the terminal to stop the application, then run it again using npm run dev.

Checkpoint: You should now be able to log in, browse to the External API page, and click the Ping API button to make an API request. The response should then display in the browser.

Use Auth0 for FREE