如何在自定义中间件中使用 csurf?

How to use csurf within a custom middleware?

我已经设法让 csurf 在我的 express 应用程序中作为常规中间件工作。但是,我想将它添加到我的自定义身份验证中间件中,以避免必须在每个路由中包含 csurf 并避免忘记使用它。我应该如何在自定义中间件中调用 csurf

例如,假设我有这个中间件使用 express-session 来限制登录用户的访问:

export const auth = async (req, res, next) => {
  const { uid } = req.session;

  try {
    const user = await User.query().findById(uid);
    req.session.role = user.role;
    next();
  } catch {
    throw new PrivateRouteError();
  }
};

有办法做到这一点,但我无法实现它。这是我尝试过的:

export const auth = async (req, res, next) => {
  const csrf = csurf({ cookie: true, ignoreMethods: [] });

  csrf(req, res, async () => {
    const { uid } = req.session;

    try {
      const user = await User.query().findById(uid);
      req.session.role = user.role;
      next();
    } catch {
      throw new PrivateRouteError();
    }
  });
};

然而,结果是 csurf 不会阻止对丢失的 CSRF 令牌的访问,并且 PrivateRouteError 不会被捕获并导致应用程序崩溃(如果用户未通过身份验证,如果他们是它工作正常)。

有没有一种巧妙的方法可以将 csurf 捆绑到我的中间件中,或者我应该手动将它添加到使用 auth 中间件的所有路由中?

好吧,我昨晚显然想多了。删除 next() 调用并在 catch 块后放置 csurf 内容就足够了。

export const auth = async (req, res, next) => {
  const { uid } = req.session;

  try {
    const user = await User.query().findById(uid);
    req.session.role = user.role;
  } catch {
    throw new PrivateRouteError();
  }

  const csrf = csurf({ cookie: true, ignoreMethods: [] });
  csrf(req, res, next);
};