Как получить req.user в сервисах Nest JS - PullRequest
0 голосов
/ 04 марта 2019

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

@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 route.

Вservice Я бы сделал что-то вроде

@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) {}

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

1 Ответ

0 голосов
/ 04 марта 2019

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

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

@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, который гарантирует, что вошедший в систему пользователь имеет необходимые роли,Подробнее см. Этот ответ .

...