TS2339: Property 'user' does not exist on type 'Request'

5.1k views Asked by At

I am trying to use JwtAuthGuard to distinguish authenticated requests from the unauthenticated ones.

I did follow the official Nestjs documentation on authentification, yet, I can't make it work as I get a typescript error: TS2339: Property 'user' does not exist on type 'Request'.

bookmarks.controller.ts

import { Controller, Get, Req, UseGuards } from '@nestjs/common'
import { BookmarksService } from './bookmarks.service'
import { StandardSuccessResponse } from '../utils/standard-response.type'
import { ResponseMessage } from '../utils/response-messages.enum'
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard'

@Controller('v1/bookmarks')
export class BookmarksController {
  constructor(private bookmarksService: BookmarksService) {}

  @UseGuards(JwtAuthGuard)
  @Get()
  async getAllBookmarkedJobs(
    @Req() request: Request
  ): Promise<StandardSuccessResponse<string[]>> {
    return {
      success: true,
      data: await this.bookmarksService.getAllBookmarkedJobs(
        request.user.candidateId
      ),
      meta: null,
      message: ResponseMessage.BOOKMARKS_RETRIEVED,
    }
  }
}

strategies/jwt.strategy.ts

import { ExtractJwt, Strategy } from 'passport-jwt'
import { PassportStrategy } from '@nestjs/passport'
import { Injectable } from '@nestjs/common'

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: process.env.JWT_SECRET,
    })
  }

  async validate(payload: any) {
    return { candidateId: payload.sub }
  }
}
3

There are 3 answers

2
Jay McDoniel On

The user property is attached to the Request object via @types/passport, or by using a custom interface that extends Request and adds the type to it yourself, like so:

export interface RequestWithUser extends Request {

  user: UserType;
}
1
cojack On

Because you don't import Request from express, just add the:

import { Request } from 'express';

But you needs to have @types/passport and @types/express installed, and it will works.

1
user13284932 On

You should change @Req() to @Res() since you are getting data.

     @UseGuards(JwtAuthGuard)
     @Get()
     async getAllBookmarkedJobs(@Res() res): Promise<StandardSuccessResponse<string[]> {
        return {
          success: true,
          data: await this.bookmarksService.getAllBookmarkedJobs(
           res.user.candidateId
          ),
          meta: null,
          message: ResponseMessage.BOOKMARKS_RETRIEVED,
        }
     }