Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I'm using a passport-jwt auth strategy in my nestJS app (with authGuard), how to get access to the token payload in my controller?

I'm trying to get access to the jwt payload in a route that is protected by an AuthGuard.

I'm using passport-jwt and the token payload is the email of the user.

I could achieve this by runing the code bellow:

import {
    Controller,
    Headers,
    Post,
    UseGuards,
} from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { AuthGuard } from '@nestjs/passport';

@Post()
@UseGuards(AuthGuard())
async create(@Headers() headers: any) {
    Logger.log(this.jwtService.decode(headers.authorization.split(' ')[1]));
}

I want to know if there's a better way to do it?

like image 317
TheAngularGuy Avatar asked Apr 08 '19 09:04

TheAngularGuy


1 Answers

Your JwtStrategy has a validate method. Here you have access to the JwtPayload. The return value of this method will be attached to the request (by default under the property user). So you can return whatever you need from the payload here:

async validate(payload: JwtPayload) {
  // You can fetch additional information if needed 
  const user = await this.userService.findUser(payload);
  if (!user) {
    throw new UnauthorizedException();
  }
  return {user, email: payload.email};
}

And then access it in you controller by injecting the request:

@Post()
@UseGuards(AuthGuard())
async create(@Req() request) {
    Logger.log(req.user.email);
}

You can make this more convenient by creating a custom decorator:

import { createParamDecorator } from '@nestjs/common';

export const User = createParamDecorator((data, req) => {
  return req.user;
});

and then inject @User instead of @Req.

like image 161
Kim Kern Avatar answered Nov 15 '22 06:11

Kim Kern