What does passport.session() middleware do?

node.jsSessionAuthenticationExpresspassport.js

node.js Problem Overview


I am building an authentication system using Passport.js using Easy Node Authentication: Setup and Local tutorial.

I am confused about what passport.session() does.

After playing around with the different middleware I came to understand that express.session() is what sends a session ID over cookies to the client, but I'm confused about what passport.session() does and why it is required in addition to express.session().

Here is how I set up my application:

// Server.js configures the application and sets up the webserver

//importing our modules
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
var mongoose = require('mongoose');
var passport = require('passport');
var flash = require('connect-flash');

var configDB = require('./config/database.js');

//Configuration of Databse and App

mongoose.connect(configDB.url); //connect to our database

require('./config/passport')(passport); //pass passport for configuration

app.configure(function() {

    //set up our express application

    app.use(express.logger('dev')); //log every request to the console
    app.use(express.cookieParser()); //read cookies (needed for auth)
    app.use(express.bodyParser()); //get info from html forms

    app.set('view engine', 'ejs'); //set up ejs for templating

    //configuration for passport
    app.use(express.session({ secret: 'olhosvermelhoseasenhaclassica', maxAge:null })); //session secret
    app.use(passport.initialize());
    app.use(passport.session()); //persistent login session
    app.use(flash()); //use connect-flash for flash messages stored in session

});

//Set up routes
require('./app/routes.js')(app, passport);

//launch
app.listen(port);
console.log("Server listening on port" + port);

node.js Solutions


Solution 1 - node.js

passport.session() acts as a middleware to alter the req object and change the 'user' value that is currently the session id (from the client cookie) into the true deserialized user object.

Whilst the other answers make some good points I thought that some more specific detail could be provided.

app.use(passport.session());

is equivalent to

app.use(passport.authenticate('session'));

Where 'session' refers to the following strategy that is bundled with passportJS.

Here's a link to the file: https://github.com/jaredhanson/passport/blob/master/lib/strategies/session.js

And a permalink pointing to the following lines at the time of this writing:

var property = req._passport.instance._userProperty || 'user';
req[property] = user;

Where it essentially acts as a middleware and alters the value of the 'user' property in the req object to contain the deserialized identity of the user. To allow this to work correctly you must include serializeUser and deserializeUser functions in your custom code.

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

passport.deserializeUser(function (user, done) {
    //If using Mongoose with MongoDB; if other you will need JS specific to that schema.
    User.findById(user.id, function (err, user) {
        done(err, user);
    });
});

This will find the correct user from the database and pass it as a closure variable into the callback done(err,user); so the above code in the passport.session() can replace the 'user' value in the req object and pass on to the next middleware in the pile.

Solution 2 - node.js

From the documentation

> In a Connect or Express-based application, passport.initialize() > middleware is required to initialize Passport. If your application > uses persistent login sessions, passport.session() middleware must > also be used.

and

> Sessions > > In a typical web application, the credentials used to authenticate a > user will only be transmitted during the login request. If > authentication succeeds, a session will be established and maintained > via a cookie set in the user's browser. > > Each subsequent request will not contain credentials, but rather the > unique cookie that identifies the session. In order to support login > sessions, Passport will serialize and deserialize user instances to > and from the session.

and

> Note that enabling session support is entirely optional, though it is > recommended for most applications. If enabled, be sure to use > express.session() before passport.session() to ensure that the login > session is restored in the correct order.

Solution 3 - node.js

It simply authenticates the session (which is populated by express.session()). It is equivalent to:

passport.authenticate('session');

as can be seen in the code here:

https://github.com/jaredhanson/passport/blob/42ff63c/lib/authenticator.js#L233

Solution 4 - node.js

While you will be using PassportJs for validating the user as part of your login URL, you still need some mechanism to store this user information in the session and retrieve it with every subsequent request (i.e. serialize/deserialize the user).

So in effect, you are authenticating the user with every request, even though this authentication needn't look up a database or oauth as in the login response. So passport will treat session authentication also as yet another authentication strategy.

And to use this strategy - which is named session, just use a simple shortcut - app.use(passport.session()). Also note that this particular strategy will want you to implement serialize and deserialize functions for obvious reasons.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGeorges KrinkerView Question on Stackoverflow
Solution 1 - node.jslindsaymacveanView Answer on Stackoverflow
Solution 2 - node.jsJosh C.View Answer on Stackoverflow
Solution 3 - node.jsJared HansonView Answer on Stackoverflow
Solution 4 - node.jsuniwalkerView Answer on Stackoverflow