Passport.js无法序列化用户

时间:2013-03-11 23:43:14

标签: node.js express passport.js

我只使用passport.js进行谷歌,Facebook和Twitter登录。

Node.js v0.8.19 with express.js 3.1.0,passportjs version 0.1.16。 (passport-facebook - 0.1.5,twitter - 0.1.4 passport-goolge-oauth - 0.1.5)

运行一小时左右的应用程序后,一切都运行良好,一段时间后,护照会停止将用户序列化到req.user会话中。

Facebook和谷歌正在接收来自各自api的完整数据

passport.use(new FacebookStrategy({
    clientID: FACEBOOK_APP_ID,
    clientSecret: FACEBOOK_APP_SECRET,
    callbackURL: "http://localhost:3000/auth/facebook/callback"
  },
  function(accessToken, refreshToken, profile, done) {
      var temp = {} 
      temp.name = profile.displayName
      temp.id = profile.id
      console.log(temp)
      return done(null, temp);
}));

此处的console.log将成功打印用户ID和名称,但是在调用

之后
passport.serializeUser(function(user, done) {
  done(null, user);
});

passport.deserializeUser(function(obj, done) {
  done(null, obj);
});

序列化和反序列化取自passport-facebook example.

用户不会被附加到req.user。

Twitter永远不会那么远,在回到回调网址后,twitter会给出错误:

Error: failed to find request token in session
[03/11 23:28:24 GMT]     at Strategy.OAuthStrategy.authenticate            

注意:这些失败只发生一段时间后,工作正常一段时间。这就是为什么我认为这可能是一个内存问题,比如我将会话保存在内存而不是内存。

这是我的快速应用配置

app.configure(function(){
  app.set('port', process.env.PORT || 8080);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.cookieParser());
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(express.cookieSession({ secret: 'tobo!', cookie: { maxAge: new Date(Date.now() +     3600000), }}));
  app.use(passport.initialize());
  app.use(passport.session());
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
});

我查看过邮件列表等,但找不到符合此问题的内容。 我已经检查了我的localhost和nodejitsu服务器。一切都有效,然后失败。

3 个答案:

答案 0 :(得分:26)

首先,您必须了解序列化和反序列化的含义。

1)serializeUser根据您的第一个问题,在您返回done(null, user)时,获取用户对象并在会话中存储您想要的任何信息。

2)deserializeUser获取存储在会话中的信息(由cookieSession在每个请求中发送)并检查会话是否仍然对用户有效,并且if(!err) done(null,user)为真,让用户保持会话,其中else done(err,null)将其从会话中删除,在检查会话是否超时后,将您重定向到app.get('/auth/:provider/callback')发送给用户的任何内容。这应该澄清你的第二个问题。

答案 1 :(得分:6)

我仍然不明白为什么会出现这个问题但我通过以下方式解决了这个问题。

更改

  app.use(express.cookieSession({ secret: 'tobo!', cookie: { maxAge: new Date(Date.now() +     3600000), }}));

app.use(express.cookieSession({ secret: 'tobo!', maxAge: 360*5 }));

我认为序列化整个用户对象应该有效,因为deserializeUser只会传回传递的cookie。但是,通过不序列化整个用户对象,它正在运行。

passport.serializeUser(function(user, done) {
    console.log('serializeUser: ' + user._id)
    done(null, user._id);
});

passport.deserializeUser(function(id, done) {
    db.users.findById(id, function(err, user){
        console.log(user)
        if(!err) done(null, user);
        else done(err, null)  
    })
});

自从我这样做以后,我遇到了问题。

答案 2 :(得分:0)

//app.use(session(...)) must comes before app.user(passport.session())
//other wise items will not be save or serialize to session


app.use(
  session({
    secret: process.env.SESSION_SECRET,
    resave: false,
    saveUninitialized: false,
  })
);


app.use(passport.session());