Passport (Authentication)

Strategy

  • Implement the strategy logic based on using existing strategy (e.g : passport-local, passport-jwt)

auth.module.ts
@Module({
  imports: [
    PassportModule,
    // if implementing jwt strategy
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  controllers: [AuthController],
  exports: [AuthService],
  providers: [AuthService, StaartStrategy],
})
export class AuthModule {}
  • Example 1

staart.strategy.ts
import { Injectable, Logger } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { Request } from 'express';
import { Strategy } from 'passport-strategy';
import { AuthService } from './auth.service';

class StaartStrategyName extends PassportStrategy(Strategy) {
  name = 'staart';
}

@Injectable()
export class StaartStrategy extends PassportStrategy(StaartStrategyName) {
  
  constructor(
    private authService: AuthService,
  ) {
    super();
  }

  private safeSuccess(result: AccessTokenParsed) {
    return this.success(result);
  }
  
  async authenticate(request: Request) {
      return this.success(result);
      return this.fail('Invalid token', 401);
  }
}
  • Example 2

local.strategy.ts
import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service';

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private authService: AuthService) {
    super();
  }

  async validate(username: string, password: string): Promise<any> {
    const user = await this.authService.validateUser(username, password);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}

Guard

  • Declare the guard of using strategy

jwt-auth.guard.ts

import { IS_PUBLIC_KEY } from "@/auth/decorators/public.decorator";

@Injectable()
export class JwtAuthGuard extends AuthGuard("jwt") {
  constructor(private reflector: Reflector) {
    super();
  }
  canActivate(context: ExecutionContext) {
    const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (isPublic) {
      return true;
    }
    return super.canActivate(context);
  }
}
  • Declare the public decorator

public.decorator.ts
import { SetMetadata } from "@nestjs/common";

export const IS_PUBLIC_KEY = "isPublic";
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
  • Apply the auth guard on global level

app.module.ts
@Module({
  imports: [
    //...
  ],
  controllers: [AppController],
  providers: [
    // ...
    { provide: APP_GUARD, useClass: JwtAuthGuard },
  ],
})
export class AppModule {}

Last updated

Was this helpful?