Как обновить объект сеанса req.user, заданный паспортными данными?

Я пытаюсь сделать это с тех пор, как много дней, но все мои тесты терпят неудачу...

Пользователи моей платформы подключают их с помощью стратегий паспортных (paypal, facebook, google...).

Когда пользователь подключен, я пишу его псевдоним справа в заголовке. HTML-код заголовка генерируется из шаблона handlebars, и когда это частичное обслуживается expressjs, я отправляю объект сеанса req.user в шаблон, чтобы писать псевдоним и другую информацию...

Кстати, это отлично работает, но у меня проблема, когда пользователь обновляет свой псевдоним из своего профиля, я не могу обновить объект сеанса на стороне сервера, и если пользователь перезагрузит страницу, старый псевдоним появится снова.

И я не хочу запрашивать информацию пользователя из БД каждый раз, когда пользователь загружает страницу, поэтому я хочу сохранить эту конфигурацию:

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

Любое предложение?

На данный момент только выход из системы, а затем логин работает... Это не очень эффективно:)

ИЗМЕНИТЬ:

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

        }
    }
}

Ответ 1

Это работает и сохраняется для меня:

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

Используете ли вы кеширование на своих маршрутах, которым может потребоваться перебор до обновления?

(сериализация паспорта одинакова)

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

Ответ 2

Для "serializeUser" вы возвращаете весь пользователь... который будет сериализовывать весь объект и помещать его в файл cookie, используемый для отслеживания сеансов. Эта сериализация происходит только один раз (когда сеанс установлен). Когда приходит следующий запрос, он всегда десериализует тот же самый пользовательский объект, который вы первоначально сохранили, который не имеет никаких обновлений, которые вы ему сделали. Для этого выйдите из системы и зайдите в работу, потому что он извлекает отредактированного пользователя из вашей базы данных (я полагаю) и воссоздает cookie отслеживания сеанса.

Чтобы подтвердить этот ответ, поместите контрольную точку на "serializeUser" и обратите внимание, что она попадает только при входе в систему.

Ответ 3

У меня такая же проблема, и я нашел решение:

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

Req.login вызовет функцию сериализации и сохранит новый сеанс в db. res.end() имеет важное значение. без него сеанс не будет сохранен.

Ответ 4

Это все еще один из лучших результатов для "паспорта обновления сессии js", поэтому я подумал, что добавлю то, что сработало для меня (предоставленные ответы мне не помогли):

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

Без req.session.save() данные сеанса не будут обновляться для меня. Надеюсь, это поможет кому-то.