在 NestJs 中何时使用守卫以及何时使用中间件

hrp*_*xQ4 5 javascript node.js express typescript nestjs

我想创建一个 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();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

它只验证令牌并使用编码的令牌及其有效负载扩展请求对象。我的身份守卫

@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();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

该守卫检查令牌有效载荷中提供的用户是否有效。如果一切正常,我应该在哪里将用户附加到请求对象?据我所知,守卫只检查某些事情是否正确。但我不想在令牌中间件中保留所有这些逻辑。在 auth Guard 中完成验证后,我可以在哪里将数据库用户附加到请求中?

Jay*_*iel 5

如果你想做一些类似于 Passport 的事情,你总是可以将用户附加到req.user,这在 Node.JS 世界中被视为非常标准的 ting。

给你的附带问题:有什么理由不让两个守卫接连工作?有一个警卫来检查令牌是否存在并且确实是一个有效的令牌,一个用于验证令牌上的用户确实是有效的。这样你就不会使用中间件(主要是为了兼容性而包括在内)并且仍然具有分离的逻辑。