Try using session middleware for sessions, such as express-session :
var session = require('express-session'); // Code to set up your app var app = express(); // Make sure to replace "somethingSecret" with your own secret value app.use(session({secret: "somethingSecret", resave: true, saveUnitialized: false}));
I wrote an application very close to the one you provided, and saw the same problem, which was strange for me, because I used to use express and passport before. When I realized that I did not use the middleware for the sessions, I added express-session and voila middleware; set-cookie .
Please note, however, that this code is not yet ready for release. From the express-session repository:
Warning Server-side storage on the server side of the MemoryStore is not intended for production environments by default. This will be a memory leak under most conditions, does not scale in one process and is intended for debugging and development.
For a list of stores, see compatible session stores .
[EDIT]
Using this code (User is shaded to always return the same value):
var bodyParser = require('body-parser'); var express = require('express'); var http = require('http'); var passport = require('passport'); var LocalStrategy = require('passport-local').Strategy; var session = require('express-session'); // Stub of User schema for testing var User = { findOne: function(user, callback) { callback(null, { id: 1234, username: user.username, password: 'foo' }); }, findById: function(id, callback) { callback(null, { id: 1234, username: 'user', password: 'foo' }); } }; var strategy = new LocalStrategy( { session: true }, function (username, password, done) { User.findOne({ username: username }, function(err, user) { if (err) { return done(err); } if (!user) { return done(null, false, { message: 'Incorrect username.' }); } if (user.password !== password) { return done(null, false, { message: 'Incorrect password.' }); } return done(null, user); }); }); function genuuid(req) { return "Test UID"; } var app = express(); var router = express.Router(); app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); app.use(passport.initialize()); app.use(session({ genid: function(req) { return genuuid() // use UUIDs for session IDs }, secret: "somethingSecret", cookie: {maxAge: 60000 }, resave: true, saveUninitialized: false })); passport.use(strategy); passport.serializeUser(function(user, done) { done(null, user.id); }); passport.deserializeUser(function(id, done) { User.findById(id, function(err, user) { done(err, user); }); }); app.post('/login', passport.authenticate('local', { successRedirect: '/', failureRedirect: '/login' })); server = http.createServer(app).listen(51015, function(){ console.log('Express server listening on port ' + app.get('port')); });
Test run:
var should = require('should'); var assert = require('assert'); var request = require('request'); var querystring = require('querystring'); it('Login should redirect to home and return a user token', function(done) { var postData = querystring.stringify({ username : 'user', password : 'foo' }); var options = { uri: 'http://' + '127.0.0.1' + ':' + '51015' + '/login', followRedirect: false }; request.post(options) .form(postData) .on('response', function(res) { console.log(res.headers); res.statusCode.should.equal(302); }) .on('data',function(data) { should.exist(data); should.fail(0,1,'Test not implemented'); done(); }) .on('error', function(e) { should.fail(0,1,'Problem with request: ' + e.message); }); });
Gives the following result; note the set-cookie header:
mocha { 'x-powered-by': 'Express', location: '/', vary: 'Accept', 'content-type': 'text/plain; charset=utf-8', 'content-length': '35', 'set-cookie': [ 'connect.sid=s%3ATest%20UID.NC0hY3rYGMdnN560ewpf%2FaJbO%2BNd9M7QLz3gnse0eLs; Path=/; Expires=Wed, 09 Sep 2015 13:08:06 GMT; HttpOnly' ], date: 'Wed, 09 Sep 2015 13:07:06 GMT', connection: 'close' } 1) Login should redirect to home and return a user token 0 passing (69ms) 1 failing 1) Login should redirect to home and return a user token: Uncaught AssertionError: Test not implemented
With the exception of the missing User schema and hard-coded configuration values, my code should be the same as yours, so I kind of don't understand how you don't get the set-cookie header.
Do you use any other middleware for expression that could affect your session or cookies?
[EDIT 2]
The problem is that (in your repository ) you add session middleware in a different area than the one in which server.listen is executed, so the changes made to the app do not actually affect it.
Instead of starting listening to the server in front of a group of tests, you should run it once for each test and immediately pass all the parameters you need. I sent a transfer request to your repository with details on how I can do this, since it is not a small amount of code and will not really fit in here.
Please take the time to read and understand the changes, because I was worried about sending a session token, and I can not guarantee if other functions affected these changes.