Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update req.user session object set by passportjs?

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

        }
    }
}
like image 663
G33k Labs Avatar asked Dec 11 '13 14:12

G33k Labs


3 Answers

This works and persists for me:

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

Are you employing caching on your routes that might need busting before refresh?

(passport serialize is the same)

passport.serializeUser(function(user, done) { done(null, user); });
passport.deserializeUser(function(obj, done) { done(null, obj); });
like image 67
Will Stern Avatar answered Sep 18 '22 14:09

Will Stern


I got the same problem and finally I found the solution:

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

The req.logIn will call serialize function and save a new session to db. res.end() is important. without it the session will not be saved.

like image 27
Quan Duong Avatar answered Sep 19 '22 14:09

Quan Duong


This is still one of the top results for 'update session passport js', so I thought I'd add what worked for me (the provided answers didn't work for me):

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

Without req.session.save() the session data would not update for me. Hope this helps someone.

like image 26
Reynaerde Avatar answered Sep 18 '22 14:09

Reynaerde