我想创建一个NestJs应用,并希望有一个中间件来验证请求对象中的令牌,并且要有一个验证卫士来验证令牌有效载荷中的用户。
通过拆分,我希望进行彻底的分离。首先是我的中间件
@Injectable()
export class TokenMiddleware implements NestMiddleware {
use(req: any, res: Response, next: NextFunction) {
try {
const headers: IncomingHttpHeaders = req.headers;
const authorization: string = headers.authorization;
const bearerToken: string[] = authorization.split(' ');
const token: string = bearerToken[1];
// !! Check if token was invalidated !!
req.token = token;
req.tokenPayload = verifyToken(token);
next();
} catch (error) {
throw new UnauthorizedException();
}
}
}
它仅验证令牌,并使用编码的令牌及其有效载荷扩展请求对象。我的身份验证管理员
@Injectable()
export class AuthenticationGuard implements CanActivate {
constructor(private readonly usersService: UsersService) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const request: any = context.switchToHttp().getRequest();
try {
const user: any = request.tokenPayload;
if (!user) {
throw new Error();
}
const findByIdDTO: FindByIdDTO = { id: user.id };
const existingUser: UserRO = await this.usersService.findById(findByIdDTO);
if (!existingUser) {
throw new Error();
}
// attach the user to the request object?
return true;
} catch (error) {
throw new UnauthorizedException();
}
}
}
此防护程序检查令牌有效载荷中提供的用户是否有效。如果一切正常,我应该在哪里将用户附加到请求对象?据我所知,警卫只会检查是否正确。但是我不想将所有这些逻辑保留在令牌中间件中。在auth Guard中完成验证后,在哪里可以将数据库用户附加到请求?
[如果您想做类似于Passport的操作,则可以始终将用户附加到req.user
,这在Node.JS世界中被视为非常标准的标准。
为您提供的另一个问题:是否有没有两个后卫立即接班的后卫?有一个警卫人员检查令牌是否存在并且确实是有效令牌,并且有一个用于验证令牌中的用户确实有效的令牌。这样,您就无需使用中间件(出于兼容性的考虑,通常将其包括在内),并且仍然具有独立的逻辑。
Where can I attach the database user to the request after finishing the validation in the auth guard?
我相信您注意到,Guard应该验证给定用户是否有权使用给定方法。
根据您的需求,您可以进入不同的路径:
1]使用护照和一种策略来做您需要做的事情(https://stackoverflow.com/a/57929429/4319037我已经为此写了几句话)。此外,它已经涵盖了提取令牌所需的大部分代码。
@Injectable()
export class HttpStrategy extends PassportStrategy(Strategy) {
constructor(private readonly authService: AuthService) {
super()
}
async validate(token: string) {
const user = await this.authService.findUserByToken(token);
if (!user) {
throw new UnauthorizedException();
}
return user;
}
}
2)在控制器/方法级别使用Interceptor
将用户附加到给定的请求(如果缺少令牌,则抛出);您的Guard将已经收到user
,因此您可以验证用户是否具有执行该方法的正确角色/权限。
[如果我误解了您想实现的目标或需要更多特定方式的详细信息,请告诉我,谢谢!