PassportJS: How to get req.user in my views

express, node.js, passport.js

Solution

Use dynamic helpers. Here's an example of my barebones `user` object:

app.dynamicHelpers({
    user: function(req, res){
        var roles, name;

        if (req.session && req.session.auth == true) {
            roles = ['member'];
            name = (req.session.user) ? req.session.user.name : 'Registered member';
            id = (req.session.user) ? req.session.user.id : 0;
        }
        else {
            roles = ['guest'];
            name = 'Guest';
            id = null;
        }

        return {
            name: name, 
            id: id,
            roles: roles,
            isGuest: roles.indexOf('guest') !== -1,
            isAdmin: roles.indexOf('admin') !== -1
        }
    }
});

Then from views you can simply use `#{user.name}` or ` if user.isAdmin` etc as object `user` is now accessible to other parts of the app.

You can add it to app.js or require from an external file. I keep all of my dynamic helpers under /utils/helpers.js

Problem

I am using pssportjs with express 2.x and a sessions storage. After a login I am getting req.User only once. As soon as I redirect again req.User is undefined. Here is my config: ``` passport.serializeUser(function(user, done) { done(null, user._id); }); passport.deserializeUser(function(userId, done) { User.findOne({_id: userId} ,function(err, user){ done(err, user); }); }); // Authentication Strategy passport.use(new FacebookStrategy({ clientID: CONFIG.fb.appId, clientSecret: CONFIG.fb.appSecret, callbackURL: CONFIG.fb.callbackURL }, function(accessToken, refreshToken, profile, done) { // asynchronous verification, for effect... process.nextTick(function () { User.findOne({ 'accounts.uid': profile.id, 'accounts.provider': 'facebook' }, function(err, olduser) { if(olduser) { done(null, olduser); } else { var newuser = new User(); var account = {provider: "facebook", uid: profile.id}; newuser.accounts.push(account); newuser.firstname = profile.name.givenName; newuser.lastname = profile.name.familyName; newuser.email = "TBD..."; newuser.save(function(err) { if(err) { throw err; } done(null, newuser); }); } }); }); } )); var app = module.exports = express.createServer(); // configure express app.configure(function(){ app.set('views', __dirname + '/views'); app.set('view engine', 'ejs'); app.use(express.compiler({ src : __dirname + '/public', enable: ['less']})); app.use(express.cookieParser()); app.use(express.bodyParser()); app.use(express.methodOverride()); //app.use(express.session({ secret: "keyboard cat" })); app.use(express.session({ secret: "victory cat", store: new MongoStore({ url: CONFIG.dbMongo.url }) })); app.use(passport.initialize()); app.use(passport.session()); app.use(app.router); app.use(express.static(__dirname + '/public')); }); ``` These are my routes: ``` app.get('/auth/facebook', passport.authenticate('facebook', { scope: ['user_status', 'user_photos'] })); app.get('/auth/facebook/callback', passport.authenticate('facebook', { successRedirect: '/index', failureRedirect: '/' })); app.get('/index', function(req, res) { res.render('index.ejs', { siteTitle: "Welcome", siteUrl: CONFIG.server.siteUrl, user: req.user }); }); ``` And finally this is how I am trying to access the user object in my view: ``` <div class="page-header"> <h3><%= siteTitle %></h3> </div> <% if (!user) { %> <p>Not logged in !</p> <% } else { %> <p>Hello, <%= user.firstname %> <%= user.lastname %>.</p> <% } %> ``` After authenticating with facebook my view displays firstname and lastname correctly. After another page request req.User is undefiend (deserializing is not being invoced). What am I doing wrong?

Original source

Related problems