如何正确使用 passport_ldapauth 的会话?

How do I properly use sessions with passport_ldapauth?

我已经阅读了文档并有一个 expressjs 应用程序使用 passport_ldapauth 和会话处理登录和注销端点。使用 sequelize 将会话存储到数据库中,并将仅包含会话 ID、过期时间、路径和域的 cookie 存储到浏览器中。

我现在正在尝试保护我的其他端点。在控制台中,我可以看到反序列化器首先被命中,正确的查询被发送到数据库的会话 table,通过正确的会话 ID 查找我的用户并找到它。

但是随后 - passport_ldapauth 被调用并且由于没有密码,我收到了 "Missing credentials" 的闪现消息和 400 return.

我认为这就是 kav 在此处的第二条评论 (https://github.com/vesse/passport-ldapauth/issues/53) 中所指的内容,但没有得到答复。

也许我把这个复杂化了?一旦我让用户登录我的其他路线,我是否应该简单地切换到 'session' 策略(如果存在)而不是 'ldapauth' ?或者这应该有效但不是?还是我做错了什么?

这是有问题的路线:

api.post('/role/add', passport.authenticate(
    'ldapauth', {session: true, failureFlash: true}
  ), (req, res, next) => {
    Roles.create(req.body).then(
      role => res.json(role)
    ).catch(err => {
      if (err) {
        console.log(err);
        next(err);
      }
    });
  });

还需要我提供什么来帮助我?

也许我的序列化器或反序列化器有问题?它们似乎适用于 login/logout 端点。见下文:

passport.serializeUser(function(user, done) {
    let sessionUser = {
      username: user.sAMAccountName,
      sessionID: user.sessionID
    };
    done(null, sessionUser);
  });
  
passport.deserializeUser(function(user, done) {
    Session.findOne({where: {sid: user.sessionID}}).then(user => {
      return done(null, user);
    });
  });

请注意,从 Active Directory returned 的用户对象是巨大的,这就是为什么我将整个对象重写为最少的用户名和会话 ID。我不确定,但我认为由 findOne 编辑的 return 用户可能是也可能不是数据库 'data' 列中包含的 'passport' 对象。唔。我需要确保它是吗?用户可能是数据库中的整行。

好吧,这太简单了,但我在官方文档中找不到任何地方。所以对于那些难以摸索护照的人,这是我发现的。

req.isAuthenticated()

只需编写您自己的中间件函数,在您的路由之上或在单独的文件中,如下所示:

const unAuthMsg = 'You are not authorized for this endpoint.';

export const ensureAuthenticated = (req, res, next) => {
  if (req.isAuthenticated()) {
    next();
  } else {
    res.status(401).json({"message": unAuthMsg});
  }
};

然后像这样在你的路线中使用它:

api.post('/role/add', ensureAuthenticated, (req, res, next) => {
Roles.create(req.body).then(role => {
  return res.json(role)
}).catch(err => {
  if (err) {
    console.log(err);
    next(err);
  }
});
  });

就是这样。