JwtStrategy is an essential mechanism for authenticating users through JSON Web Tokens (JWT). It leverages the passport-jwt package to validate JWTs, ensuring that only authenticated users can access protected routes and resources in your application. This strategy is pivotal in verifying user credentials and attaching user details to requests, thereby fortifying the security of web applications.

Implementing JwtStrategy

The JwtStrategy is typically employed for securing routes, utilizing decorators such as @UseGuards in NestJS.
@UseGuards(JwtAuthenticationGuard)
@Controller("projects")
export class ProjectController {
  // Controller logic...
}

Usage Across Application Levels

  • Flexible Application: The JwtAuthenticationGuard, which employs JwtStrategy, can be applied at both controller and method levels.

Customization of the Validate Method

  • Adaptability: The validate(payload: any) method in JwtStrategy can be tailored to specific project requirements. By default, it locates and attaches the user to the request, but it can be modified to fit different authentication needs.

Integration with Express

  • Utilizing Express Request: The @Req() req: Request parameter in controller methods originates from Express. This demonstrates NestJS’s seamless integration with Express, allowing easy access to request details.
user.controller.ts
import { Request } from "express";

@UseGuards(JwtAuthenticationGuard)
@Controller("users")
export class UserController {
  constructor(private readonly userService: UserService) {}

  //! UPDATE USER / ME

  @UseGuards(PermissionGuard)
  @Permissions(ServerPermission.UPDATE_USER_ME, true)
  @Put("/me")
  async updateUserMe(
    @Body() updateUserDto: UpdateUserDto,
    @Req() req: Request
  ): Promise<any> {
    return await this.userService.updateOne({
      conditions: { _id: req["user"]._id }, // Accessing user details from request
      changes: updateUserDto,
      projection: UserProtection.DEFAULT(),
    });
  }
}

JWT Module Configuration

  • Setting Up JWT Module: The JWT strategy is configured within the JwtModule. This setup typically occurs in the AuthenticationModule and is crucial for the strategy’s functionality:
JwtModule.registerAsync({
  imports: [ConfigModule, UserModule],
  useFactory: async (configService: ConfigService) => ({
    secret: configService.get('JWT_SECRET_KEY'),
  }),
  inject: [ConfigService],
}),

Refresh Token Strategy

  • Dedicated Refresh Token Logic: A separate strategy, named jwt.strategy.refresh.ts, is used for managing refresh tokens. It follows similar logic but operates with a distinct secret and is targeted for specific routes:
import { Request } from 'express';

@UseGuards(JwtRefreshAuthenticationGuard)
@Post('/refresh-token')
async getRefreshToken(
  @Body() refreshToken: RefreshTokenDto,
  @Req() req: Request,
): Promise<any> {
  // Refresh token logic...
}