I have several NodeJS (Express 4) servers behind a Nginx proxy. Everything works fine, except for the cookies: upon each ajax CORS request, I seem to get a new regenerated session ID value in the returned Set-Cookie header.
I have worked on this for hours, looked into dozens of websites. Even this did not seem to help: Node.js + Nginx - What now?
My Nginx listens to port 80, and defines multiple servers, one for each subdomain: myapp.local, api.myapp.local, static.myapp.local.
My NodeJS Express 4 servers listen to a different port each one (8081, 8082, ...)
When calling api.myapp.local/login in ajax from myapp.local, I receive the proper data and session ID, but in the response I seem to have a newly generated session ID, which messes up everything and prevents me from having a healthy session.
Here is the conf for my api.myapp.local server:
server {
listen 80;
server_name api.myapp.local;
error_log logs/api.error.log notice;
access_log logs/api.access.log;
location / {
if ($request_method !~ ^(GET|HEAD|POST|OPTIONS)$ ) {
return 405;
}
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, HEAD, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Referer,Accept,Origin,DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,X-HTTP-Method-Override,If-Modified-Since,Cache-Control,Content-Type,Cookie';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, HEAD, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Referer,Accept,Origin,DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,X-HTTP-Method-Override,If-Modified-Since,Cache-Control,Content-Type,Cookie';
add_header 'Access-Control-Max-Age' 1728000;
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, HEAD, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Referer,Accept,Origin,DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,X-HTTP-Method-Override,If-Modified-Since,Cache-Control,Content-Type,Cookie';
add_header 'Access-Control-Max-Age' 1728000;
}
proxy_pass http://localhost:8081;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-NginX-Proxy true;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Here is my NodeJS server (straightforward):
var app = express();
app.enable('trust proxy');
/**
* Session
*/
require('../common/webapp_session.js')(app, conf);
var iPort = process.env.PORT || conf.port;
app.listen(iPort);
console.log('API on port ' + iPort);
Now my session stuff (in webapp_session.js):
app.use(cookieParser());
console.log('** COOKIE SESSION');
console.log(conf.cookie);
app.use(session({
secret: conf.cookie.secret,
name: conf.cookie.name,
cookie: {secure: conf.cookie.secure, domain: conf.cookie.domain, maxAge: 1000*60*60*24}
}));
And last my ajax call:
$.ajax('http://api.myapp.local/login',
{
type: 'POST',
data: oForm.serialize(),
crossDomain: true,
xhrFields: {
withCredentials: true
},
success: function(res)
{
// ...
}
});
EDIT: forgot the Express configuration for session:
{ cookie:
{ path: '/',
_expires: Mon Jun 16 2014 23:24:06 GMT+0200 (Paris, Madrid (heure d’été)),
originalMaxAge: 86400000,
httpOnly: true,
secure: false,
domain: '.myapp.local' } }
Thank you a lot in advance for any help, I'm getting mad with this issue :-/