authenticationnestjspassport-jwt

Get user data in RoleGuard with passport JWT authentication


I've managed to get JWT authentication in my nestJS application. Now I want to implement the role guard and have therefore to check the role of the authenticated user. Therefore, I thought of requesting the respective user role from the database. But this call is async and this is not doable within the guard.

My question is: How can I get the user role information within the Guard? I could put the information in the JWT token, but this seems not right to me, or am I wrong?


Solution

  • Here, Implementing Passport JWT you can put your findUser in the validate function that is async. And then create a decorator to return the user Auth JWT in decorator in NESTJS

    So you need to do some things like this

    //jwt.strategy.ts
    import { ExtractJwt, Strategy } from 'passport-jwt';
    import { PassportStrategy } from '@nestjs/passport';
    import { Injectable } from '@nestjs/common';
    import { jwtConstants } from './constants';
    
    @Injectable()
    export class JwtStrategy extends PassportStrategy(Strategy) {
      constructor() {
        super({
          jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
          ignoreExpiration: false,
          secretOrKey: jwtConstants.secret,
        });
      }
    
      async validate(payload: any) {
        // Your JWT payload
        // Insert here the findOne from you're BDD
        return { userId: payload.sub, username: payload.username };
      }
    }
    

    And then

    //user.decorator.ts
    import { createParamDecorator, ExecutionContext } from '@nestjs/common';
    
    export const User = createParamDecorator((data: any, ctx: ExecutionContext) => {
      const request = ctx.switchToHttp().getRequest();
      return request.user;
    });
    

    And in your controller juste use

    //user.controller.ts
    import { User } from './user.decorator';
    
    @Get()
    async getUser(@User() user) {
      //console.log(user);
    }