Authentication with NestJS
Overview
In this lecture, we will cover various aspects of implementing authentication in a NestJS application. This includes setting up sign-up, login, and refresh token endpoints, generating access and refresh tokens, and using guards for protecting routes.
Project Setup
- Basic NestJS Application
- Generate Resources
- Create a
nor
module.
- Create
schemas
and dto
folders.
- Installing Dependencies
- Mongoose:
npm install @nestjs/mongoose mongoose
- Class Validator:
npm install class-validator class-transformer
- Bcrypt:
npm install bcrypt @types/bcrypt
- UUID:
npm install uuid
- NestJS JWT:
npm install @nestjs/jwt
- NestJS Config:
npm install @nestjs/config
Creating Schemas
- User Schema
- Defined with
@Schema
decorator.
- Properties:
name
, email
(unique), and password
.
DTO (Data Transfer Object)
- Signup DTO
- Fields:
name
, email
, password
.
- Class validators: Ensures data validation and constraints.
- Login DTO
Validation Pipe
- Apply global validation pipe in
main.ts
.
- Configuration:
whitelist: true
, forbidNonWhitelisted: true
.
Setting Up Mongoose
- Configure MongoDB connection in
app.module.ts
using MongooseModule.forRoot()
.
- Import user model into
nor.module.ts
using MongooseModule.forFeature()
.
- Inject user model into AuthService.
Signup Endpoint
- Controller Setup
- Create route:
@Post('signup')
.
- Method:
async signup(@Body() signupData: SignupDto)
.
- Service Method
- Check if email exists, hash password with bcrypt, save user.
- Hashing password:
bcrypt.hash(password, 10)
(salt rounds = 10).
Login Endpoint
- Controller Setup
- Create route:
@Post('login')
.
- Method:
async login(@Body() credentials: LoginDto)
.
- Service Method
- Check if email exists, compare passwords with bcrypt.
- Generate access and refresh tokens using
jsonwebtoken
.
JWT Configuration
- Default Configuration
- Secret: Store securely (e.g., in environment variables).
- Modules:
JwtModule
in app.module.ts
.
- Token Generation
- Access Token: Short-lived, includes
userId
in payload, set expiry (e.g., 1h
).
- Refresh Token: Long-lived, needs to be saved in the database.
Creating and Storing Refresh Tokens
- Schema:
RefreshTokenSchema
- Properties:
token
, userId
, expiryDate
.
- Service Method
- Generate token with
uuidv4()
, store in database.
- Expiry: Current date + 3 days.
Refresh Token Endpoint
- Controller Setup
- Create route:
@Post('refresh')
.
- Method:
async refreshTokens(@Body() refreshTokenDto: RefreshTokenDto)
.
- Service Method
- Verify token existence and non-expiry, generate new tokens.
Guards for Route Protection
- Custom Guard
- Class:
AuthGuard implements CanActivate
.
- Import
JwtService
, verify token from headers.
- Check token validity, attach user info to request object.
- Apply guard at the controller or route level.
Unauthorized and Error Handling
- Controller Return Values
- For invalid/expired tokens, throw
UnauthorizedException
.
- Error Logging
- Log errors for troubleshooting (e.g., JWT expired messages).
Testing and Debugging
- Tools: Postman for API testing.
- Timestamps and Expiry
- Monitor token expiry, validate error handling for expired tokens.
Conclusion
- Summary
- Implemented user signup and login with JWT-based authentication.
- Created access and refresh tokens, and guarded routes using custom guards.
- Next Steps
- Future videos on changing passwords, resetting passwords via email, roles and permissions.
- Resources
- Links to NestJS playlist and related videos for more in-depth understanding.
Feel free to refer back to these notes for a high-level overview and key implementation details from the lecture on NestJS authentication.