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.
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:
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.