如何更新由护照设置的req.user会话对象? [英] How to update req.user session object set by passportjs?

查看:159
本文介绍了如何更新由护照设置的req.user会话对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图这样做,因为很多天,但所有的测试都失败了...



我的平台上的用户通过使用护照的策略(paypal ,facebook,google ...)。



当用户连接时,我在标题右侧写下他的昵称。
标头的html代码是从句柄模板生成的,当这个部分由expressjs提供时,我将req.user会话对象发送给模板,以便写入昵称和其他信息。 p>

顺便说一句,这很有用,但是当用户从他的个人资料更新他的昵称时,我有一个问题,我无法更新服务器端的会话对象,如果用户重新加载页面,旧的昵称再次出现。



我不想每次用户加载页面时要求DB的用户信息,所以我想保留这个配置:

  //  - 护照会话设置
passport.serializeUser(function(user,done){done (null,user);});
passport.deserializeUser(function(obj,done){done(null,obj);});

我的中间件设置本地人:

  //  - 从模板中设置可访问的数据
res.locals = _.extend(res.locals,{
user:req.user,
查询:req.url,
标题:app.config.title,
url:app.config.url
});

我的失败:

  //尝试直接更新req.user:not persistent 
req.user.nickname = User.get('nickname');

//尝试更新护照会话:异常错误
req.session.passport.user = User.toJSON();

//尝试替换完整的会话对象:not persistent
var session = req.session;
session.passport.user = User.toJSON();
req.session = session;

任何建议?



只有一个注销,然后一个登录工作...这不是真的很有效:)



编辑

  //应用程序路由器
var Router = require('./ helpers / router.js');

//创建Express Server
var app = express()。http()。io();

// - Init应用程序路由器
var router = new Router(app);

// - 框架中间件
app.use(router.middleware);

########################
/ ***
* APP ROUTER
** /

//导出路由器
module.exports = function(app){

//设置实例
var router = this ;

//返回路线注册&中间件方法
return {

// - 注册路由
注册: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();
}
} (错误){
console.log('error'+ err)

});
});
});
});
},

// - 绑定中间件
中间件:function(req,res,next){

//获取当前路径
console.log(Middleware ::+ req.url);

//添加用户信息
res.locals = _.extend(res.locals,{
user:req.user,
query:req.url,
标题:app.config.title,
url:app.config.url
});

//转到下一个
next();

}
}
}


解决方案

对于'serializeUser',您将返回整个用户...将序列化整个对象并将其放在用于跟踪会话的cookie中。该序列化只发生一次(会话建立时)。当下一个请求进入时,它总是反序列出您原来存储的完全相同的用户对象,它们没有对其进行任何更新。这就是为什么要注销并重新登录工作,因为它从数据库中检索编辑的用户(我假设),并重新创建会话跟踪cookie。



要确认此答案,在'serializeUser'上放置一个断点,并注意到只有在登录时才会触发。


I'm trying to do this since a lot of days but all my tests fails...

Users on my platform connect them by using passportjs strategies (paypal, facebook, google...).

When the user is connected I write his nickname on the right in the header. The html code of the header is generated from a handlebars template, and when this partial is served by expressjs, I send the req.user session object to the template in order to write nickname and other informations...

By the way, this works great but I have a problem when the user update his nickname from his profile, I can't update session object on the server side and if the user reload the page, the old nickname appears again.

And I don't want to request user informations from DB every time a user load a page, so i want to keep this config :

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

My middleware to set locals :

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

My fails :

// 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;

Any suggestion ?

For moment, only a logout then a login works... It's not really efficient :)

EDIT :

// 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(); 

        }
    }
}

解决方案

For 'serializeUser' you are returning the entire user... which will serialize the entire object and put it inside the cookie used to track sessions. That serialization only happens one time (when the session is established). When the next request comes in, it always deserializes that exact same user object you stored originally, which doesn't have any updates you made to it. That's why logging out and logging back in works, because it retrieves the edited user from your database (I assume), and recreates the session tracking cookie.

To confirm this answer, put a breakpoint on 'serializeUser', and notice that it is only hit when you login.

这篇关于如何更新由护照设置的req.user会话对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆