Как получить req.user в сервисах Nest JS

В контроллере я добавляю пользовательский объект с защитой, внедряю какую-то службу и вызываю эту службу, чтобы получить какой-то ответ. Я удалил много кода для краткости.

@Controller()
@UseGuards(AuthGuard())
export class UserController() {
   constructor(private readonly userService: UsersService) {
   }

   @Get(':id')
   async findOne(@Param('id') id) {
      return await this.userService.findOne(id);
   }
}

Поскольку у меня есть AuthGuard, теперь я знаю, что пользователь вошел в систему перед входом в маршрут :id.

В службе я бы сделал что-то вроде

@Injectable()
export class UsersService {
   async findOne(id: number): Promise<User> {
      return await this.usersRepository.findOne({where: {id: id}});
   }
}

Но, конечно, мы хотим иметь некоторые проверки того, что вошедший в систему пользователь имеет доступ к пользователю, которого он запрашивает. Теперь вопрос в том, как мне получить текущего вошедшего в систему пользователя. Я могу отправить его как параметр из контроллера, но, поскольку для многих серверных частей потребуется проверка безопасности для текущего пользователя, я не уверен, что это хорошая идея.

@Get(':id)
async findOne(@Param('id') id, @Req() req: any) {
   return await this.userService.findOne(id, req.user);
}

В идеале, что не работает, я мог бы получить его в UserService:

async findOne(id: number, @Req req: any): Promise<User> {
   if (id === req.user.id || req.user.roles.contains('ADMIN')) {
      return await this.userRepository.findOne({where: {id: id}});
   }
}

Или, возможно, через инъекцию в конструкторе UserService

constructor(@Inject(REQUEST_OBJECT) private readonly req: any) {}

Итак, есть ли лучший способ отправить объект пользователя через серверную часть, чем всегда отправлять объект запроса при каждом вызове функции?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
23
0
29 637
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Обновление марта 2019 г.

Начиная с версии v6, теперь вы можете внедрить объект request в поставщик с областью действия запроса:

import { REQUEST } from '@nestjs/core';
import { Request } from 'express';

@Injectable({ scope: Scope.REQUEST })
export class UsersService {
  constructor(@Inject(REQUEST) private readonly request: Request) {}
}

Устаревший ответ

Невозможно внедрить пользователя (или запрос) непосредственно в службу. Nest.js пока не поддерживает поставщиков с областью запроса. Это может измениться в версии 6. До тех пор служба ничего не знает о запросе.

Вошедший пользователь

Вы можете создать индивидуальный декоратор@User. Использование декоратора предпочтительнее, чем внедрение объекта запроса, потому что тогда теряются многие преимущества гнезда (например, приемники и фильтры исключений).

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

А затем используйте его следующим образом:

@UseGuards(AuthGuard()) 
@Get(':id)
async findOne(@Param('id') id, @User() user) {
   return await this.userService.findOne(id, user);
}

Роли

Вы можете создать RolesGuard, который гарантирует, что у вошедшего в систему пользователя есть необходимые роли. Подробнее см. в этом отвечать.

Другие вопросы по теме