如何更新由passportjs设置的req.user会话对象?

我试图做很多天,但所有的testing失败…

我的平台上的用户使用passportjs策略(paypal,facebook,google …)连接它们。

当用户连接时,我在标题的右侧写上他的昵称。 头文件的html代码是从handlebars模板生成的,当这个部分由expressjs服务的时候,我把req.user会话对象发送给模板,以便编写昵称和其他信息。

顺便说一下,这工作的很好,但我有一个问题,当用户从他的configuration文件更新他的昵称,我不能更新服务器端的会话对象,如果用户重新加载页面,旧的昵称再次出现。

而且我不想每次用户加载一个页面都要求数据库的用户信息,所以我想保留这个configuration:

// -- Passport session setup passport.serializeUser(function(user, done) { done(null, user); }); passport.deserializeUser(function(obj, done) { done(null, obj); }); 

我的中间件设置当地人:

 // -- Set accessible datas from the template res.locals = _.extend(res.locals, { user: req.user, query: req.url, title: app.config.title, url: app.config.url }); 

我失败了:

 // Trying to update req.user directly : not persistent req.user.nickname = User.get('nickname'); // Trying to update passport session : exception error req.session.passport.user = User.toJSON(); // Trying to replace full session object : not persistent var session = req.session; session.passport.user = User.toJSON(); req.session = session; 

任何build议?

暂时只有一个注销然后login工程…这不是真的有效:)

编辑

 // Application router var Router = require('./helpers/router.js'); // Create Express Server var app = express().http().io(); // -- Init app router var router = new Router(app); // -- Framework Middleware app.use(router.middleware); ######################### /*** * APP ROUTER **/ // Export router module.exports = function(app) { // Set instance var router = this; // Returns routes register & middleware methods return { // -- Register routes register: function() { requirejs(['routes'], function(routes) { _.each(routes, function(name, route) { app.get(route, function(req, res, next) { requirejs(['views/'+name], function(view) { if ( view ) { var _view = new view(_.extend(req.params, {server: {req: req, res: res, next: next}})); _view.render(name, req, res, next); } else { next(); } }, function (err) { console.log('error' + err) }); }); }); }); }, // -- Bind middleware middleware: function(req, res, next) { // Get the current path console.log("Middleware :: "+req.url); // Add user informations res.locals = _.extend(res.locals, { user: req.user, query: req.url, title: app.config.title, url: app.config.url }); // Go next next(); } } } 

这工作,并坚持我:

 req.session.passport.user.nickname = 'mynewnickname' 

你在你的路线上使用caching,可能需要刷新前刷新?

(护照序列号是一样的)

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

对于'serializeUser',你正在返回整个用户…将序列化整个对象,并把它放入用于跟踪会话的cookie。 该序列化只发生一次(当会话build立时)。 当下一个请求进入时,它总是反序列化你最初存储的完全相同的用户对象,它没有任何更新。 这就是为什么注销和重新login的原因,因为它从数据库中检索编辑的用户(我假设),并重新创build会话跟踪cookie。

为了确认这个答案,在“serializeUser”上放置一个断点,并注意它只在login时被触发。

我得到了同样的问题,最后我find了解决办法:

 var user = newDataObj; req.login(user, function(error) { if (!error) { console.log('succcessfully updated user'); } }); res.end(); // important to update session 

req.login将调用序列化函数并将新的会话保存到数据库。 res.end()很重要。 没有它会话将不会被保存。

这仍然是“更新会议护照js”的最重要结果之一,所以我想我会添加什么对我有用(所提供的答案不适合我):

 req.session.passport.user.updatedfield= 'updatedvalue' req.session.save(function(err) {console.log(err);} 

没有req.session.save()会话数据不会更新我。 希望这有助于某人。