'nestjs return undefined in Public Guards

I follow this link https://docs.nestjs.com/security/authentication#enable-authentication-globally

I went ahead and create a public guard

But it does not recognize my requests when I put @Public on top of any method

and returns undefined !

I want to detect usser is logged on public routes

JwtAuthGuard

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);
  }
}

Public Decorator

export const IS_PUBLIC_KEY = 'isPublic';
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);

Sample controller

@Public()
@Get()
async find(@LoginUser() user: User): Promise<any> {
    console.log(user);
    // the user is undefined even after login
}


Solution 1:[1]

You set the route to be public and have a clause in your guard that says "if the route is public return true before attempting a login". If you want to login regardless of if the route is public or not, and then return ture at all times you can do something like

export class JwtAuthGuard extends AuthGuard('jwt') {
  constructor(private reflector: Reflector) {
    super();
  }

  canActivate(context: ExecutionContext) {
    const canAct = await (super.canActivate(context) as Promise<boolean>)
    const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    return isPublic ?? canAct;
  }
}

This will now have passport attempt a login from the get-go. So long as you don't throw an error in the valdiate method, or anything the validate method calls, everything should proceed as Passport does the login, check if the route is public, and return true if so, return if the login was successful if the route is not public.

Solution 2:[2]

write this:

constructor(@Inject(Reflector) private reflector: Reflector){
    super();
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jay McDoniel
Solution 2 Antonino pecoraro