【问题标题】:Session issues with PassportjsPassportjs 的会话问题
【发布时间】: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 的实现添加到您的问题中吗?另外,“无法序列化”究竟是什么意思?
  • 序列化和反序列化函数在哪里。也在这里写他们的代码
  • 另外,“不能序列化”到底是什么意思?我的意思是,如果我检查了会话文件,则根本没有写入护照会话。

标签: node.js express passport.js


【解决方案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,有什么更好的解决方案吗?
猜你喜欢
  • 2015-01-16
  • 2015-11-25
  • 2021-02-20
  • 2017-08-16
  • 2016-04-14
  • 2013-02-04
  • 2014-04-06
  • 2016-09-13
  • 1970-01-01
相关资源
最近更新 更多