javascript - 在 NestJs 中什么时候使用守卫什么时候使用中间件

标签 javascript node.js typescript express nestjs

我想创建一个 NestJs 应用程序,并希望有一个中间件验证请求对象中的 token ,以及一个验证 token 负载中的用户的身份验证守卫。

通过拆分这个,我希望能有一个干净的分离。首先是我的中间件

@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();
    }
  }
}

它仅验证 token 并使用编码 token 及其有效负载扩展请求对象。我的授权守卫

@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();
    }
  }
}

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

最佳答案

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

你的附带问题:有什么理由不让两个守卫接二连三地发挥作用?有一名 guard 检查 token 是否存在并且确实是有效 token ,还有一名 guard 用于验证 token 上的用户确实有效。这样您就不会使用中间件(主要是为了兼容性而包含中间件)并且仍然具有分离的逻辑。

关于javascript - 在 NestJs 中什么时候使用守卫什么时候使用中间件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58196496/

相关文章:

javascript - NodeJS 示例应用无法启动,无法找到 'config'?

javascript - 在多用户中使用 localStorage

javascript - 使用 then/catch 语法使用 axios 分别捕获 4xx 和代码错误

node.js - 通过 Chai 发布请求

javascript - Node.js、Express 和依赖注入(inject)

angular - 构建 Firestore 事务操作

javascript - 如何使用 replace() 替换 Javascript 中的星号?

javascript - id 字段的 Mongoose 请求返回 id 和 _id

TypeScript 导入模块在当前范围内不存在

angular - 共享模块导出