jwtcontrollernestjsauthorizationguard

How do I access my user in a valid JWT for unprotected routes?


I'm using NestJS 10 with TypeORM 0.3.17. I have this method in my controller

  @UseGuards(AccessTokenGuard)
  @Post()
  create(
    @Req() req: Request,
    @Body() createOrderDto: CreateOrderDto,
  ): Promise<Order> {
    const userId = req.user['sub'];
    return this.ordersService.create(userId, createOrderDto);
  }

and this is how the guard is defined

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

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

My question is, what if I want to unprotect the route (it is not required to submit a valid JWT token to access the route), but I would like to access the user if there is a valid JWT submitted. I'm noticing that if I remove the

@UseGuards(AccessTokenGuard)    

line, I can't get access to the "req.user['sub']" object anymore.


Solution

  • req.user is populated by parsing the JWT that is sent which is what passport-jwt is doing. If you don't call to the AccessTokenGuard then the jwt is never parsed and req.user is never populated. If you want, you can make an OptionalTokenGuard that calls to the canActivate of AuthGuard('jwt') but returns true regardless the outcome, so that req.user might be populated. This would look something like

    @Injectable()
    export class OptionalTokenGuard extends AuthGuard('jwt') {
    
      async canActivate(context: ExecutionContext) {
        await super.canActivate(context);
        return true;
      }
    }