【问题标题】:express-jwt middleware is not being executed in typescript decoratorexpress-jwt 中间件未在 typescript 装饰器中执行
【发布时间】:2021-04-25 08:52:27
【问题描述】:

我为 express 编写了自定义装饰器。这是控制器装饰器:

export function controller(routePrefix: string) {
  return function (target: Function) {
    const router = AppRouter.getInstance();
    for (let key in target.prototype) {
      const routeHandler = target.prototype[key]; //getLogin
      const path = Reflect.getMetadata(
        MetadataKeys.Path,
        target.prototype,
        key
      );
      const method: Methods = Reflect.getMetadata(
        MetadataKeys.Method,
        target.prototype,
        key
      );
      const middlewares =
        Reflect.getMetadata(MetadataKeys.Middleware, target.prototype, key) ||
        [];
      if (path) {
        router[method](
          `${routePrefix}${path}`,
          ...middlewares,
          routeHandler
        );
      }
    }
  };
}

这里是 use 装饰器:

export function use(middleware: RequestHandler | jwtRequestHandler) {
  return function (target: any, key: string, desc: PropertyDescriptor) {
    const middlewares =
      Reflect.getMetadata(MetadataKeys.Middleware, target, key) || [];
    Reflect.defineMetadata(
      MetadataKeys.Middleware,
      [...middlewares, middleware],
      target,
      key
    );
  };
}

路线如下:

@controller("/api/v1/portfolios")

@post("/")
  @use(checkJwt)
  @use(checkRole("admin"))
  async createPortfolio(req: Request, res: Response) {
    const portfolioData = req.body;
    console.log("portfoliodata", portfolioData);
    const userId = req.user.sub;
    const portfolio = new Portfolio(portfolioData);
    console.log("portfoliom");
    portfolio.userId = userId;
}

express-jwt 接受请求并分配 user 并将其添加到 req obj。

`user=req.user`

这里是checkJwt 中间件:

export const checkJwt = jwt({
  secret: jwksRsa.expressJwtSecret({
    cache: true,
    rateLimit: true,
    jwksRequestsPerMinute: 10,
    // this link is always provided by auth0 providers
    jwksUri: process.env.JWKS_URI as string,
  }),
  //   this is in the API/identifier in auth0.com
  audience: process.env.AUTH0_AUDIENCE,
  //   issuer should end with "/"
  issuer: process.env.ISSUER,
  algorithms: ["RS256"],
});

但是 checkJwt 没有被执行。 checkRole 被执行,这意味着我的设置是正确的。因为 checkJwt 没有被执行,req.user 没有被定义,所以checkRole 捕捉到错误。这是checkRole

export const checkRole = (role: string) => (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  let user: { [key: string]: string } = {};
  user = req.user;
  if (user && user[process.env.AUTH0_NAMESPACE + "/roles"].includes(role)) {
    next();
  } else {
    return res
      .status(401)
      .send("You are not authorized to access this resource!");
  }
};

当我从客户端发布投资组合时,checkRole 发送此错误“您无权访问此资源!”。

我不知道如何让 express 执行 checkJwt。

【问题讨论】:

    标签: typescript express jwt decorator express-jwt


    【解决方案1】:

    您需要注意装饰器的顺序。 The documentation 声明装饰器从上到下调用​​,但结果从下到上返回。

    所以你的代码应该是这样的:

    @post("/")
    @use(checkRole("admin"))
    @use(checkJwt)
    async createPortfolio(req: Request, res: Response) {
       //Your code
    }
    

    【讨论】:

    • 我知道我错过了一个简单的点。谢谢!
    【解决方案2】:

    现在我明白为什么装饰器被称为从上到下,但结果是从下到上:

    调用装饰器可以这样写:

      post(use(createPortfolio))
    

    post 调用useuse 调用createPortfolio,这意味着createPortfoli 将位于调用堆栈的顶部。所以createPortfolio会先被执行,返回它的值然后从调用栈中弹出

    【讨论】:

      猜你喜欢
      • 2018-05-12
      • 2021-12-15
      • 2018-06-08
      • 2018-01-31
      • 1970-01-01
      • 2023-03-04
      • 2017-11-15
      • 2021-11-25
      • 2018-04-06
      相关资源
      最近更新 更多