编辑
我混合了 Authentication 和 Authorization:一旦用户通过身份验证,我想要实现的就是授权。
我不得不使用 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 };
}
}
请注意我如何将自定义名称“own”作为PassportStrategy 的第二个参数传递,以将其与“jwt”区别开来。它的守卫:
@Injectable()
export class OwnAuthGuard extends AuthGuard('own') {}
这可行,但我想知道这是否是好方法...
如果以后我想为管理员用户修改用户怎么办?
我应该创建一个检查role === Role.ADMIN || req.params.id === payload.sub 的第四个策略吗?
我想我错过了一些东西。应该有一种方法可以创建一种策略,它只验证 jwt,另一个只验证 userId,另一个只验证角色,并在将警卫应用于我的路线时根据需要组合它们。