In this step by step tutorial, you will learn how to secure your REST API endpoints using Auth0.
- Create a NestJs Application
- Add Two More API Endpoints
- Create Authorization Module and Authorization Guard
- Modify the Authorization Guard
- Create New API for Auth0
- Let’s Use a .env File
- Add the ConfigService to the Authorization Guard
- Finally Protect an API Endpoint
1. Create a Nestjs Application
Step 1 – Install the Nestjs command line interface.
npm install -g @nestjs/cli
Step 2 – Create an Nestjs Application using the command below
nest new nestjs-auth-demo
Choose npm when prompted
Step 3 – Once the application is created, you can open it using VS Code or any other editor.
Step 4 – Launch it using the command:
npm run start -dev
Step 5 – Go to http://localhost:3000 to make sure it works. You will see the message “Hello World”
2. Add Two More Endpoints
We now need to add two endpoints: one that would be accessed without authentication and a second one that we would require authentication.
Step 1 – Open the app.controller.ts file and add the following after the getHello() function
@Get('/public') getPublic(): string { return this.appService.getPublic(); } @Get('/protected') getProtected(): string { return this.appService.getPrivate(); }
Step 2 – Open the app.service.ts file and add the following as well
getPrivate(): string { return 'This is a public resource. Welcome visitor!'; } getPublic(): string { return 'This is a protected resource. Welcome member'; }
Step 3 – Restart the server and test the all the endpoints. For now, we’ve not protected any of them
3. Create an Authorization Module and Authorization Guard
With an authorization guard, we would protect certain endpoints. This means that to access this endpoints, and authorization token will be required.
Step 1 – Generate authorization module using the command below:
nest generate module authorization --no-spec
Step 2 – Generate an authorization guard using the command below:
nest generate guard authorization --no-spec
Step 3 – (optional) – Move the authorization guard into the authorization folder
Step 4 – Install the following dependency:
npm install jwks-rsa express-jwt
4. Modify the Authorization Guard
We now need open the authorization guard file and make some changes
Step 1 – Add the following imports while removing the observable import
import { expressJwtSecret, GetVerificationKey } from 'jwks-rsa'; import {promisify} from 'util'; import {expressjwt} from 'express-jwt';
Step 2 – Inside the canActivate function, create a checkJwt function like shown below:
const checkJwt = promisify( jwt({ secret: expressJwtSecret({ cache: true, rateLimit: true, jwksRequestsPerMinute: 5, jwksUri: '', }) as GetVerificationKey, audience: '', issuer: '', algorithms: ['RS256'] }), );
Step 3 – Replace the return true line with the code below:
try{ await checkJwt(req, res); return true; } catch(error) { throw new UnauthorizedException(error); }
Step 4 – Change the canActivate function to an async function
5. Create a New API for Auth0
Now this part is very important as you need to complete it to continue with the next steps.
Step 1 – Visit https://manage.auth0.com/ and create an account free.
Step 2 – In your terminal, install Auth0 cli using the command below:
brew install auth0/auth0-cli/auth0
This command is for Mac. For Auth0 cli installation on Windows or Linux, see procedure here.
Step 3 – In your application terminal run the following to install the deploy cli
npm i -g auth0-deploy-cli
Step 4 – Run the following command to create a new Auth0 API
auth0 apis create
Provide a name for it nest-api-demo
You will notice that the auth0 api is created with the domain kindson.eu.auth0.com (yours may be different, so watch the video for clarification)
6. Let’s Use a .env File
We would have to create a .env file and add our variables in it.
Step 1 – Create a .env file
Step 2 – Add the following in it.
AUTH0_AUDIENCE=nest-api-demo AUTH0_DOMAIN=https://kindson.eu.auth0.com/
Step 3 – To use the environment variables, install the nest config library using the command below:
npm install @nestjs/config
Step 4 – Import the config into the authorization guard file like so:
import { ConfigService } from '@nestjs/config';
Step 5 – Add the ConfigModule to the imports section of the app module like so:
imports: [AuthorizationModule, ConfigModule.forRoot()],
7. Add the ConfigService to the Authorization Guard
To use the ConfigService in the Authorization Guard, follow the steps below:
Step 1 – Create two variables to hold the values of the AUTH0_AUDIENCE and the AUTH0_DOMAIN like so:
private AUTH0_AUDIENCE: string; private AUTH0_DOMAIN: string;
Step 2 – Create a constructor in the authorization.guard.ts file and inject the ConfigService like so:
constructor( private configService: ConfigService){ this.AUTH0_AUDIENCE = this.configService.get('AUTH0_AUDIENCE'); this.AUTH0_DOMAIN = this.configService.get('AUTH0_DOMAIN'); }
Step 3 – Now update the jwt audience, issuer(domain) and the jwt secret jwkUri. Modified part of the code is given below:
... jwksUri: `${this.AUTH0_DOMAIN}.well-known/jwks.json`, }), audience: this.AUTH0_AUDIENCE, issuer: this.AUTH0_DOMAIN, ...
8. Finally, to protect and api endpoint,
Simply add this annotation to the controller endpoint:
@UseGuards(AuthorizationGuard)
At this point, you can now start the server and try to access the api endpoints. You’ll see that that protected endpoint would require authorization. This response is shown below using Postman
You can get the jwt token from your Auth0 dashboard and include it in the request and then you can access it.