Passport.js 一条路线的多种策略。仅对一种策略使用会话

Passport.js multiple strategies for a single route. Use sessions for only one strategy

我正在使用 ExpressNodeJSPassportJSTypeScript 构建一个 API 端点。我想为此端点允许两种类型的身份验证。 SAML(用于人类)和用于自动化的令牌。对于人工身份验证,我使用 passport-saml 策略。对于令牌身份验证,我使用 passport-http 基本身份验证。到目前为止,我的代码如下所示:

import session from "express-session";

const samlStrategy = getSamlStrategy();
const basicStrategy = getBasicStrategy();

app.use((req, res, next) =>
  session({
    // store sessions in db
  })(req, res, next)
);

app.use(passport.initialize());
app.use(passport.session());

passport.serializeUser((user, done) => {
  //...
});

passport.deserializeUser((username, done) => {
  //...
});

passport.use(samlStrategy);
passport.use(basicStrategy);

const requireApiAuth: express.Handler = (req, res, next) => {
  if (req.user) {
    next();
  } else {
    res.status(401);
  }
};

const tryTokenAuth: express.Handler = (req, res, next) => {
  if (!req.user && req.headers.authorization && req.headers.authorization.indexOf("Basic") > -1) {
    passport.authenticate("basic", { session: false })(req, res, next);
  } else {
    next();
  }
};

//...
// SAML endpoints here
//...

app.use(
  "/api",
  tryServiceUserAuth,
  requireApiAuth,


基本思想是中间件函数 tryTokenAuth 将检查请求中是否已存在 user。如果存在,则意味着人类已经通过 SAML 身份验证登录。如果没有 user 并且请求指定了基本授权,那么我们应该使用 basic 策略进行身份验证。目前,这是有效的。我能够使用 /api 路由的任一策略进行身份验证。

问题是,即使我为 basic 身份验证指定 {session: false},我仍然会在响应中收到发回的会话 cookie。我的数据库中正在记录一个会话。我不明白我需要配置什么来防止这种行为。我不希望在使用 basic 身份验证时创建会话。

有什么办法可以做到吗?

事实证明,在身份验证调用中指定 session: false 只会阻止 passport 将其会话数据添加到请求会话中。仍在创建会话的原因是因为我的配置说:

app.use((req, res, next) =>
  session({
    // store sessions in db
  })(req, res, next)
);

为了在使用基本身份验证时防止出现这种情况,我必须更新为:

app.use((req, res, next) => {
  if (req.headers.authorization && req.headers.authorization.indexOf("Basic") > -1) {
    next();
  } else {
    session({
      // store sessions in db
    })(req, res, next)
  }
});