Passportjs 的会话问题

Posted

技术标签:

【中文标题】Passportjs 的会话问题【英文标题】:Session issues with Passportjs 【发布时间】:2017-10-30 13:10:49 【问题描述】:

我正在尝试在我的 nodejs 应用程序中通过 express4 使用 passportjs。出于测试目的,我使用 session-file-store 来保持会话。

我设置会话和护照的方式:

this.app.use(session(
  secret: process.env.SESSION_SECRET || configuration.session_secret,
  store: new fileStore(),
  resave: false,
  saveUninitialized: false
));

// config authentication
this.app.use(passport.initialize());
this.app.use(passport.session());
// Configure Passport
passport.use('local-login', new localStrategy.Strategy(
    (username, password, done) => 
      Services.users.authenticatePromise(username, password).then(
          function(token) 
            done(null, token);
          ,
          function(err) 
            done(null, false, err);
          ,
      ).done();
    ,
));
    // Serialize user in session
passport.serializeUser((token: AccessToken, done) => 
  let user = 
    _token: token.accessToken,
    _expiryInAt: token.expiryInMs + new Date().getTime(),
  ;
  done(null, user);
);

passport.deserializeUser((sessionUser, done) => 
  done(null, sessionUser);
);

但是,我遇到的问题是,如果在用户登录之前我没有在会话中写入任何内容,则 passportjs 可以正常工作。但是,如果我尝试将一些数据写入会话中,例如购物车详细信息,那么 passportjs 将无法再将用户令牌序列化到会话存储中。所以登录不能成功。

我错过了什么?

【问题讨论】:

你在做req.session = ... 或类似的事情吗? IE。用新的东西覆盖整个会话对象。 不,我做了类似的事情:if (!req.session['basket']) req.session['basket'] = ; 抱歉,这应该不是问题,因为它无法序列化。您可以将passport.serializeUser/deserializeUser 的实现添加到您的问题中吗?另外,“无法序列化”究竟是什么意思? 序列化和反序列化函数在哪里。也在这里写他们的代码 另外,“不能序列化”到底是什么意思?我的意思是,如果我检查了会话文件,则根本没有写入护照会话。 【参考方案1】:

我可以看到你的代码有一些问题。

首先,serializeUser 应该接受一个对象并返回一个字符串(通常是唯一的 id 或数据库键)。您的函数当前接受一个字符串并返回一个对象;那是倒退。

其次,deserializeUser 应该接受一个字符串并返回一个用户对象。您的函数当前接受一个对象并返回该对象。

最后,serializeUserdeserializeUser 必须互为倒数;也就是说,passport可以调用deserializeUser(serializeUser(user))取回原来的用户对象。

所以你会想要这样的东西:

passport.serializeUser((user, done) => 
  return user.id;
);

passport.deserializeUser((id, done) => 
  getUserFromDatabase(id: id, function(err, user) 
    if (err) 
      done(err, null); // something went wrong; return error
     else if (!user) 
      done(null, false); // no user found; return `false`
     else 
      done(null, user);  // return user
    
  );
);

更多信息请看这里:Understanding passport serialize deserialize

【讨论】:

你是对的。这肯定不是最佳做法,但我认为这不是我看到的问题的原因。首先,当我在登录前没有在会话中写入任何内容时,这个 serializeUser/deserializeUser 工作正常。它可以将用户序列化到会话存储中并对其进行反序列化。而且我只是想在passportjs中使用api令牌而不是用户ID,有什么更好的解决方案吗?

以上是关于Passportjs 的会话问题的主要内容,如果未能解决你的问题,请参考以下文章

PassportJS 会话混淆了

带有猫鼬的 PassportJS 只发送一半的数据

Passport js 无法跨域维护会话

PassportJS - 自定义回调并将 Session 设置为 false

通过令牌进行身份验证,如果令牌失败,则通过会话进行身份验证,使用 Passport?

passportJS - passport-facebook 无法获取失败重定向路由