Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

express.js sessions with reverse proxy

I've setup an Apache reverse proxy to forward api.mydomain.com to localhost:2000 which works just fine.

However, the real issue i'm having is in regard to sessions - it seems that the req.session's aren't being stored when querying via api.mydomain.com. Sessions will work just fine visiting from localhost:2000.

I assume this has something to do with the proxied domain...

server.js

var express = require('express'),
    app = express();

app.enable('trust proxy');

app.configure(function() {
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.cookieParser());
    app.use(express.session({ secret: 'supersecret'});
    app.use(app.router);
});

app.get('/session', function(req, res, next){ 
    console.log(req.session.username)
    // this will be undefined when called from  api.mydomain.com...
});


app.post('/session', function(req, res, next){ 
    req.session.username = 'my username';
});

apache config

<VirtualHost *:80>
    ServerName api.mydomain.com   
    ProxyPass / http://localhost:2000/
    ProxyPassReverse / http://localhost:2000/

    ProxyPreserveHost On
    ProxyPassReverseCookieDomain api.domain.com localhost:2000
    ProxyPassReverseCookiePath / /
</VirtualHost>

EDIT

Notably, for further testing - adding the below code before app.use(app.router) in app.configure() ....

app.use(function (req, res) {
    res.send('<h2>Hello, your session id is ' + req.sessionID + '</h2>');
});

will result in the following (each line represents a new GET /session request to the app - node hasn't restarted either).

localhost:2000

Hello, your session id is sHkkESxJgzOyDhDwyTjwpNzq
Hello, your session id is sHkkESxJgzOyDhDwyTjwpNzq
Hello, your session id is sHkkESxJgzOyDhDwyTjwpNzq

api.mydomain.com

Hello, your session id is uuo4U5ierZAG8LSH1BdwTlVf
Hello, your session id is 8BxL97Bo35SDt4uliuPgnbia
Hello, your session id is 0xkqZZpzQNvTsQpbJtUlXgkR

Setup info

NodeJS v0.8.8

Apache v2.4.2

ExpressJS v3.0.0rc4

UPDATE 2

Well, I've so far resolved to simple use mydomain.com/api, as that seems to fix everything. So I suppose it's just something to do with how Apache handles domain communication with Express!

like image 722
crawf Avatar asked Sep 06 '12 08:09

crawf


4 Answers

Judging by Apache ProxyPass and Sessions This apache config Maybe ...

<VirtualHost *:80>
    ServerName api.mydomain.com   
    ProxyPass / http://localhost:2000/
    ProxyPassReverse / http://localhost:2000/
    ProxyPassReverseCookiePath / /
</VirtualHost>
like image 58
Ben Evans Avatar answered Nov 18 '22 13:11

Ben Evans


I experienced this exact issue and tried everything else mentioned here without success. The final piece of the puzzle was adding the following to Apache's SSL Virtual Host config:

RequestHeader set X-Forwarded-Proto "https"

This particular gem I discovered in one of the last comments at https://github.com/expressjs/session/issues/251

So overall the things I implemented to fix it were as follows:

  1. Changes to Apache Config:

RequestHeader set X-Forwarded-Proto "https" ProxyPassReverseCookiePath / /

  1. Changes to Node App.

app.enable('trust proxy');

like image 2
Daniel C Avatar answered Nov 18 '22 14:11

Daniel C


It should be trivial to look at the session cookie being forwarded and see why your browser doesn't re-send it when proxied -- the domain or path are likely wrong.

Re: your later comments -- Maybe you really did set "ProxyPassReverseCookieDomain / /" instead of using domains as the argument?

ProxyPreserveHost would probably also indirectly work for you, but fixing up the cookie is better.

like image 1
covener Avatar answered Nov 18 '22 14:11

covener


Using this config maintains my session id on node 0.6.17, express 3.0.0rc4. Initially I had the following in the virtualhost, but even after changing to match your config, it still works.

ServerName api
ServerAlias api.internal.local

I get a Set-cookie connect.sid which is maintained.

like image 1
Brett Avatar answered Nov 18 '22 13:11

Brett