Passportjs的会话问题

时间:2017-05-30 07:13:27

标签: node.js express passport.js

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

我设置会话和passportjs的方式:

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将无法再将用户令牌序列化到会话存储中。所以登录无法成功。

我错过了什么?

1 个答案:

答案 0 :(得分:1)

您可以看到代码中的一些问题。

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

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

最后,serializeUserdeserializeUser必须相互颠倒;意思是,护照可以拨打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