Add basic auth to your NestJS REST API

In this tutorial, I will talk you through implementing basic auth to your NestJS REST API to add basic level protection to your NestJS application.

Add basic auth to your NestJS REST API

In this tutorial, I will talk you through implementing basic auth to your NestJS REST API to add basic level protection to your NestJS application. I will assume you're comfortable with NodeJS, NestJS and Typescript.

👀 Looking for header API Key auth? Check out my tutorial on implementing header API key auth.

We're going to store a username and passport in plain text in our .env file, but I strongly advise you use this as a guide and use encrypted credentials instead.

Example Repo

A GIT repo with this basic auth example can be found in my Github account:

Step 1 - Create an auth module

In your application, we will need to make use of the Passport Basic Auth module. Let's go ahead and add the dependencies with NPM:

npm i passport passport-http @nestjs/passport --save

We will also need the type definitions for passport-http:

npm i @types/passport @types/passport-http --save-dev

If your application doesn't use the NestJS config module, you will need this too:

npm i @nestjs/config --save

Let's add a username and password to our .env file:

HTTP_BASIC_USER=myusername
HTTP_BASIC_PASS=password123

Now create a new directory in your project called auth. This will store the auth module which is responsible for authenticating our application.

Inside this file, we need to create our basic strategy file. Inside the auth directory, create a new file called auth-basic.strategy.ts and add the following to this file:


import { BasicStrategy as Strategy } from 'passport-http';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ConfigService } from '@nestjs/config';

@Injectable()
export class BasicStrategy extends PassportStrategy(Strategy) {
    constructor(
        private readonly configService: ConfigService,
    ) {
        super({
            passReqToCallback: true
        });
    }

    public validate = async (req, username, password): Promise<boolean> => {
        if (
            this.configService.get<string>('HTTP_BASIC_USER') === username &&
            this.configService.get<string>('HTTP_BASIC_PASS') === password
        ) {
            return true;
        }
        throw new UnauthorizedException();
    }
}

This strategy is responsible for validating the basic username and password which is sent to our REST API when we make a HTTP call to it.

Now, still inside our auth module directory, create new file called auth.module.ts. Add the following to this file:

import { Module } from '@nestjs/common';
import { PassportModule } from '@nestjs/passport';
import { BasicStrategy } from './auth-basic.strategy';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [PassportModule, ConfigModule],
  providers: [BasicStrategy],
})
export class AuthModule {}

This is basically all we need to do for the module. Now all that's left to do is to import this into our main application.

Step 2 - Wire the auth module into the application

Inside your main app.module.ts, include AuthModule into the main import block of the @Module() decorator:


import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
// ... other import statements here
import { AuthModule } from './auth/auth.module';

@Module({
    imports: [
        ConfigModule.forRoot(),
        // ... other modules here
        AuthModule,
    ],
    controllers: [
    	// controllers here
    ],
    providers: [
    	// providers here
    ],
})
export class AppModule { }

Finally, inside our controller, we need to add the following decorator to controller methods which you want to be secured behind the basic authentication:

...
    @Get('my-endpoint')
    @UseGuards(AuthGuard('basic'))
    findOne() {
        // do something
    }
...
2

Conclusion

That's it. This is what you should need to get you up and running. I strongly suggest you implement some kind of encryption, especially if you plan on storing the usernames and passwords in the database.