TS2339: свойство ‘user’ не существует для типа ‘Request’

#typescript #express #nestjs #jwt-auth #passport-jwt

#typescript #выразить #nestjs #jwt #паспорт-jwt

Вопрос:

Я пытаюсь использовать JwtAuthGuard, чтобы отличать аутентифицированные запросы от неаутентифицированных.

Я следовал официальной документации Nestjs по аутентификации, но не могу заставить ее работать, поскольку получаю ошибку typescript: 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 }
  }
}
  

Ответ №1:

Поскольку вы не импортируете запрос из express, просто добавьте:

 import { Request } from 'express';
  

Но вам нужно иметь @types/passport и @types/express установить, и это будет работать.

Ответ №2:

user Свойство присоединяется к Request объекту с помощью @types/passport или с помощью пользовательского интерфейса, который extends Request и добавляет к нему тип самостоятельно, вот так:

 export interface RequestWithUser extends Request {

  user: UserType;
}
  

Комментарии:

1. я использую nestjs, куда я должен добавить это

2. Сделайте его интерфейсом в любом месте вашего приложения и импортируйте его, когда вам нужен полный Request тип, вместо использования Request from express

Ответ №3:

Вы должны изменить @Req() на @Res(), поскольку вы получаете данные.

      @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,
        }
     } 
  

Комментарии:

1. Использование @Res() фактически заставит Nest прекратить отправку ответа и потребует от пользователя вручную обработать его res.send() . Не рекомендуется использовать в Nest, если это не является абсолютно необходимым, и в 9 случаях из 10 есть другие способы обработки ответа.