OK, so this questions has been asked a bunch of times and in different manners, however, none of the proposed solutions have worked for me so far. I have a very simple log-in page that passes user name and password to my server and the server authenticates the user and saves the user object in the session:
App.js:
var express = require('express')
, SessionMongooseStore = require("session-mongoose")(express)
, SessionStore = new SessionMongooseStore({
url: "mongodb://localhost/MySessions",
interval: 1200000
});
var app = express();
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.session({
store: SessionStore,
cookie: {maxAge: 36000000},
secret: 'MySecret'
}));
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method- Override, Content-Type, Accept');
next();
});
Route:
app.post('/login',Session.LogIn);
Session.LogIn definition:
exports.LogIn = function(req,res){
if(req.body){
var user_name = req.body.email_address;
var pwd = req.body.password;
Store.getUser(user_name,pwd,function(err,user){
if(error) { //do something }
else{
//SAVING DATA TO THE SESSION
req.session.authenticatedUser = user;
req.session.foo = 'bar';
req.session.save();
var successResponse = {};
successResponse.redirect = '/redirect';
res.json(successResponse);
}
});
}
}
My jQuery AJAX POST:
var post = $.ajax({url: '/login',
type: "POST",
data: querystring,
xhrFields: {withCredentials: true},
success: function(data) {
if(data.code!=200){
alert('Log in failed');
}
else if(data.redirect){
window.location = data.redirect;
}
else{
alert('Could not understand response from the server');
}
}});
When I make the POST, I can see the session variables 'user' and 'foo' being set, I can print them, but when I come back to any route, the variables are undefined. Example, calling '/' after logging in:
app.get('/',function(req,res){
console.log('--------- Looking for authenticated user saved in session: ' + req.session.authenticatedUser);
console.log('--------- Foo: ' + req.session.foo);
res.render('index');
});
I get:
--------- Looking for authenticated user saved in session: undefined
--------- Foo: undefined
I have attempted to reproduce this using HTTP Poster add-on for FF and doing a POST, not using jQuery, and it works fine, the variables are saved in the session object. Every POST I've read talks about using
xhrFields: {withCredentials: true}
with my jQuery POST and using:
res.header('Access-Control-Allow-Credentials', true);
in my node js server, which I am doing as you can see from the code above, but still no luck. Any ideas?
By default, the httpOnly
flag is set to to true
in the cookie settings for express.session
thus denying access to xhr
requests, such as what jQuery does. You can enable it in the cookie configuration:
app.use(express.session({
store: SessionStore,
cookie: {
maxAge: 36000000,
httpOnly: false // <- set httpOnly to false
},
secret: 'MySecret'
}));
Now your client's cookies should be accessible to the server during an ajax request.