How to set secure cookie using heroku + node.js + express?

If you're using cookie-session it should look like this:

app.use require('cookie-session') 
   secret: '<secret>'
   secureProxy: true

Solution

The problem was that I set proxy: true in the wrong place, it should look like as follows:

...
app.enable('trust proxy'); // optional, not needed for secure cookies
app.use(express.session({
    secret : 'somesecret',
    store : ..., // store works fine, sessions are stored
    key : 'sid',
    proxy : true, // add this when behind a reverse proxy, if you need secure cookies
    cookie : {
        secure : true,
        maxAge: 5184000000 // 2 months
    }
}));
...

Add as well app.enable('trust proxy'); suggested by @friism in case you want to use req.protocol somewhere in the Heroku hosted app.


You are correct that Heroku terminates SSL before it reaches your app. That causes express to see non-ssl traffic, and that's likely why it's refusing to set the cookie when running on Heroku.

Heroku sets a X-Forwarded-Proto header with the original protocol. I haven't tested this, but according to the documentation, you have to tell express to respect the information in that header by setting trust proxy as documented here. Additional details found under req.protocol here.