node.js Passport.js 无法序列化用户

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15350704/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 13:49:45  来源:igfitidea点击:

Passport.js failing to serialize user

node.jsexpresspassport.js

提问by Eoin Murray

I am using passport.js for Google, Facebook and Twitter logins only.

我仅将passport.js 用于Google、Facebook 和Twitter 登录。

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

Node.js v0.8.19 和 express.js 3.1.0,以及passportjs 0.1.16 版。(passport-facebook - 0.1.5, twitter - 0.1.4 护照-goolge-oauth - 0.1.5)

Everything works fine for a while, after an hour or so of the app running passport.js stops serializing the user into the req.user session.

一切正常一段时间后,运行passport.js 的应用程序停止将用户序列化到req.user 会话一个小时左右后。

Facebook and google are receiving meaning full data from their respective api's

Facebook 和 google 正在从各自的 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);
}));

The console.log here will successfully print user id and name, however after calling

这里的console.log 会成功打印用户id 和name,但是调用之后

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

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

Serialize and deserialize are taken from the passport-facebook example.

序列化和反序列化取自passport-facebook示例。

The user will not be attached to req.user.

用户不会附加到 req.user。

Twitter never gets that far, after returning to the callback url, twitter gives the error:

Twitter 从来没有走那么远,在返回回调 url 后,twitter 给出了错误:

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

Note:these failures only happen after a period of time, the work properly for a while. Thats why I think it may be a memory issue, like Im saving the session in memory instead of a cooke.

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

This is my express app configuration

这是我的快速应用配置

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'));
});

I have looked at the mailing list etc, but I could not find something matching this problem. I have checked on my localhost and on a nodejitsu server. Everything works for a while then fails.

我查看了邮件列表等,但找不到与此问题匹配的内容。我已经检查了我的本地主机和 nodejitsu 服务器。一切工作一段时间然后失败。

回答by Marcel

First you must understand what serialize and deserialize are meant for.

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

1) serializeUsertake a user object and store any information you want in the session, when you return done(null, user), as per your first question.

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

2) deserializeUsertake the information stored in the session (sent by cookieSession in every request) and checks if the session is still valid for a user, and if(!err) done(null,user)is true, keeps the user in the session, where else done(err,null)removes it from the session, redirecting you to whatever your app.get('/auth/:provider/callback')sends the user to after checking if the session is timed out or not. This should clarify things for your second question.

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

回答by Eoin Murray

I still do not understand why the problem came about but I have solved it by doing the following.

我仍然不明白为什么会出现问题,但我已通过执行以下操作解决了它。

Changing

改变

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

to

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

I think that serializing the entire user object should work since deserializeUser will just pass back the passed cookie. But by not serializing the entire user object it is working.

我认为序列化整个用户对象应该可以工作,因为 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)  
    })
});

I have had zeroissues since I did this.

我曾零个问题,因为我这样做。