node.jsjwtnestjspassport-jwt

req.user if undefined in guards whileusing nest js + jwt + passport


I've implemented passport + jwt in my simple nestjs app for authentication. it's working fine. Now I want to use role-based authentication for routes but in my role.guard.ts , req.user is undefined. Please help me solve this issue.

auth.guard.ts

import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}

jwt.strategy.ts

import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { UserService } from 'src/user/user.service';
import { AuthService } from './auth.service';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(
    public authService: AuthService,
    public configService: ConfigService,
    public userService: UserService,
  ) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: configService.get('JWT_SECRET'),
      // passReqToCallback: true,
      // secretOrKey: authService.getConfig('JWT_SECRET'),
    });
  }

  async validate(payload: any) {
    const user = await this.userService.getOne(payload._id);
    console.log('user', user);
    return user;
    // return { id: payload._id };
  }
}

user.controller.ts


@Controller('users')
export class UserController {
  constructor(private userService: UserService) {}

  @Get('/')
  @UseGuards(AuthGuard('jwt'))
  @UseGuards(RolesGuard)
  getAllUsers(): any {
    return this.userService.getAll();
  }

}

role.guard.ts

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import * as jwt from '@nestjs/jwt';
import { promisify } from 'util';

@Injectable()
export class RolesGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean | Promise<boolean> {
    const req = context.switchToHttp().getRequest();

    console.log('req.user', req.user);

    return true;
  }
}


Solution

  • Don't use two @UseGuards(), use a single one and order the guards in the order you want them to execute:

    @UseGuards(AuthGuard('jwt'), RolesGuard)