Walkthrough: Identity Lab 2 Exercise 2 - Securing APIs with Auth0

If you came to this page directly, go to the first page of this lab and read through the instructions before getting started.

In this exercise, you will register the API with Auth0 so that tokens can be issued for it. You will also learn how to secure your API with Auth0. You will refactor the API that your web application is consuming by installing and configuring some libraries needed to secure it with Auth0.

To register the API with Auth0, open the Auth0 Dashboard and go to the APIs screen.

Click the Create API button. Add a descriptive Name, paste https://expenses-api into the Identifier field, and click Create.

Click the Permissions tab and add a new permission called read:reports with a suitable description. This custom permission is the one you will use to determine whether the client is authorized to retrieve expenses.

In your terminal, restart your web application with [CTRL] + [c], then npm start.

Log out of the web application by clicking logout, then log in again. When logging in, you will see a consent screen where Auth0 mentions that the web application is requesting access to the read:reports scope.

API consent screen on the authorization server

Agree to this delegation by clicking the Accept button, and Auth0 will redirect you back to the application. Now, you should still be able to see your expenses on the expenses page, localhost:3000/expenses

Application expenses page

If at any point, you want to see the consent screen again when logging in, you can go to the Users screen in the Auth0 Dashboard, click on the user you'd like to modify, click the Authorized Applications tab, find the application you're using, and click Revoke. The next time you log in, the consent screen will appear again. As mentioned earlier, the expenses API is still not secure. You can see this by navigating directly to localhost:3001. The expense data is available publicly, without an access token. The next steps will change the API to require a properly-scoped access token to view.

In your terminal, stop your API with [CTRL] + [c].

Install the express-oauth2-bearer npm package. This is an Express authentication middleware used to protect OAuth2 resources, which validates access tokens:

# Make sure we're in the right directory
    ❯ pwd
    ❯ npm install express-oauth2-bearer@0.4.0 --save
    # Ignore any warnings
    + express-oauth2-bearer@0.4.0
    added XX packages in X.XXs

Open the api/api-server.js file and add a statement to import the library. Make sure this is added after the dotenv require statement:

// api/api-server.js
    // ... other require statements
    // Add the line below 👇
    const { auth, requiredScopes } = require('express-oauth2-bearer');

Configure the Express app to use the authentication middleware for all requests:

// api/api-server.js
    // ... other require statements
    const app = express();
    // Add the line below 👇

Find the / endpoint code and update it to require the read:reports scope in access tokens. This is done by adding a requiredScopes middleware, as shown below:

// lab-02/begin/api/api-server.js
    // Change only the line below 👇
    app.get('/', requiredScopes('read:reports'), (req, res) => {
// ... leave the endpoint contents unchanged.

The next time you run your API, all requests that do not include a valid access token (expired token, incorrect scopes, etc.) will return an error instead of the desired data.

Open the api/.env file you created before and change the ISSUER_BASE_URL value to your own Auth0 base URL (same as the one in your application). The .env file should look like this:


Once again, start the API server with npm:

npm start

listening on http://localhost:3001
To test your secured API, refresh the expenses page in your application - localhost:3000/expenses. If everything works as expected, you will still be able to access this view (which means that the web app is consuming the API on your behalf). If you browse directly to the API at localhost:3001, however, you will get an error saying the token is missing.

Next →