В контроллере я добавляю пользовательский объект с защитой, внедряю какую-то службу и вызываю эту службу, чтобы получить какой-то ответ. Я удалил много кода для краткости.
@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) {}
Итак, есть ли лучший способ отправить объект пользователя через серверную часть, чем всегда отправлять объект запроса при каждом вызове функции?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


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