Nestjs + Passport: запретить пользователю 1 доступ к информации пользователя 2
Как я могу запретить пользователю 1 доступ к информации пользователя 2 с помощью паспорта в приложении Nesjs?
У меня уже есть 2 стратегии:
локальная стратегия, которая проверяет пользователя с помощью электронной почты / пароля. Маршрут, защищенный этой стратегией, возвращает токен jwt.
стратегия jwt, которая проверяет данный токен jwt.
Теперь я хочу ограничить доступ к таким маршрутам, как users/:id
в токен jwt, который фактически имеет тот же зашифрованный идентификатор пользователя.
Как это сделать?
2 ответа
РЕДАКТИРОВАТЬ
Я смешивал аутентификацию и авторизацию: я хочу добиться авторизации после аутентификации использования.
Пришлось использовать Guard:
own.guard.ts
@Injectable()
export class OwnGuard implements CanActivate {
canActivate(context: ExecutionContext): boolean {
const req = context.switchToHttp().getRequest();
return req.user.id === req.params.id;
}
}
Затем используйте его в моем маршруте:
@Get(':id')
@UseGuards(OwnGuard)
async get(@Param('id') id: string) {
return await this.usersService.get(id);
}
ОРИГИНАЛЬНЫЙ ОТВЕТ
Я создал третью стратегию на основе стратегии jwt:
@Injectable()
export class OwnStrategy extends PassportStrategy(Strategy, 'own') {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: SECRET,
passReqToCallback: true
});
}
async validate(req: Request, payload: { sub: string }) {
if (req.params.id !== payload.sub) {
throw new UnauthorizedException();
}
return { userId: payload.sub };
}
}
Обратите внимание, как я передаю собственное имя в качестве второго параметра PassportStrategy
чтобы отличить его от "jwt". Его охранник:
@Injectable()
export class OwnAuthGuard extends AuthGuard('own') {}
Это работает, но мне интересно, хороший ли это способ сделать это...
Что, если позже я захочу внести изменения для пользователей с правами администратора?
Должен ли я создать четвертую стратегию, которая проверяет, role === Role.ADMIN || req.params.id === payload.sub
?
Думаю, что-то упускаю. Должен быть способ создать стратегию, которая проверяет только jwt, еще одну - только userId, еще одну - только роль, и комбинирует их так, как я хочу, применяя охрану к моим маршрутам.
тот же случай. вы можете использовать
handleRequest
метод в карауле.
здесь вы можете получить доступ к пользовательской аутентификации и req, а затем выполнить проверку для соответствующего ресурса. проверьте мой код
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
canActivate(context: ExecutionContext) {
return super.canActivate(context);
}
handleRequest(err, user, info, context: ExecutionContext) {
const request = context.switchToHttp().getRequest<Request>();
const params = request.params;
if (user.id !== +params.id) {
throw new ForbiddenException();
}
return user;
}
}
подробнее здесь https://docs.nestjs.com/security/authentication#exnding-guards