Session: unable to use secure cookies

Created on 2 Mar 2016  路  22Comments  路  Source: expressjs/session

I am trying to set secure cookies, it does not work at first try.

I am using

 secret: sessionSecret,
      resave: false,
      saveUninitialized: true,
      cookie: {
        secure: true,
        httpOnly: true,
        domain: 'beintoo.net',
        expires: expiryDate
      }

I found function issecure relying on req.connection.encrypted here but it seems not supported anymore, see https://github.com/expressjs/express/issues/1864

Any hint?

question

Most helpful comment

Ah, should be able to get proxy_set_header X-Forwarded-Proto https; added in there and it should be good to go?

All 22 comments

Hi @fibo, is your Express server even listening on a SSL socket (https.createServer(app, options)) or are you terminating your SSL with a reverse proxy in front of your Node.js app?

Also, if you haven't already, please take a read through our documentation on this at https://github.com/expressjs/session#cookie-options and see if perhaps you just forgot to set some of those Express configurations or something.

Hi @dougwilson , I am using nginx to handle SSL. I had a look at the documentation but I could not found a solution. I found the line of code linked above cause I enabled debug with export DEBUG=express-session and saw the _not secured_ message.

I have just tryed _cookie-session_ Package and iwth the secureProxy option enabled worked almost out of the box.

Please let me know if I can contribute back with some additional info or test, otherwise close the issue.

Hi @fibo, what version of Express are you using? Have you tried adding the app.set('trust proxy', 1) to your code like in our example?

Yes, I tryed to set "trust proxy" as required in the documentation.

Unfortunately I am working on a private project right now so it is more difficult to show you. By the way, did you checked the line of code linked above? It refers to req.connection.encrypted which seems to be not valid anymore.

I am using Node v4.2.2, here are my deps:

  "dependencies": {
    "body-parser": "^1.14.1",
    "connect-ensure-login": "^0.1.1",
    "express-session": "^1.12.1",
    "debug": "^2.2.0",
    "express": "^4.13.3",
    "express-session": "^1.12.1",
    "jade": "^1.11.0",
    "mdconf": "0.0.2",
    "passport": "^0.3.2",
    "passport-local": "^1.0.0",
    "pg": "^4.4.3",
    "pg-promise": "^3.1.4",
    "pm2": "^1.0.0",
    "q": "^1.4.1",
    "sendgrid": "^2.0.0",
    "strict-mode": "^0.4.1"
  },

I did check that line, and the line is meaningless if you are using nginx, as the if check will always fail and move on. Is your nginx configured to add the X-Forwarded-Proto: https header to your node.js server?

I guess it is not, this is the config

upstream console {
    server 127.0.0.1:4000;
}

server {
    listen 443 ssl;
    ssl on;

    server_name console.beintoo.net;
    ssl_certificate /etc/nginx/ssl/www_example_net.chained.crt;
    ssl_certificate_key /etc/nginx/ssl/www_example_net.key;

    location / {
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_set_header X-NginX-Proxy true;

      proxy_pass http://127.0.0.1:4000/;
      proxy_redirect off;
    }
 }

Ah, should be able to get proxy_set_header X-Forwarded-Proto https; added in there and it should be good to go?

Sorry, I did not had time to setup a server with nginx to reproduce this latter case you proposed me, since using _cookie-session_ package worked out of the box.

Anyway, thanks for the hint, I will try it next time I will setup an express+nginx server with auth.

@dougwilson thank you very much for your support. It is thanks to people like you that internet was born. I hope you can have a lot of satisfaction from your future projects.

No problem. I think for issues like this, we can get some more information added to the README, like what the headers the secure stuff is looking for and maybe even links to configuring Apache/nginx. Since This uses the same headers that Express wants for the proxy configuration, if we get examples Apache/nginx configurations added to the exressjs.com website, we could link there from here. I think that would end up helping a lot :)

I had some trouble with this as well. By turning on cookie: { secure: true }, proxy: true, app.set('trust proxy', true), and proxy_set_header X-Forwarded-Proto $scheme; in the nginx proxy, I've gotten HTTPS cookies to work.

Here's a snip of my app:

app.set('trust proxy', true)
app.use(session({
    store: new RedisStore({
        pass: 'aaa',
    }),
    secret: 'aaa',
    proxy: true,
    resave: false,
    saveUninitialized: true,
    cookie: { secure: true }
    }))

And my nginx configuration:

# Snip of nginx proxy configuration

proxy_redirect off;
    proxy_http_version 1.1;
    proxy_pass http://127.0.0.1:port;
    proxy_set_header Host $host; 
    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;

I had the same issue and just want to thank you for helping clarify matters.

proxy_set_header X-Forwarded-Proto https; is what I was missing from my nginx config to enable secure cookies. I used it along with app.set('trust proxy', true) proxy: true, and cookie: { secure: true }

Thanks!

@tagiles it's safer not to just use true in the value of trust proxy please see the details.

Thank you @gabeio for pointing that out. I have adjusted it to use the 'subnet, ip' of the proxy. People like you and Doug who make this tech work for the rest of us ;) Cheers

Ah, should be able to get proxy_set_header X-Forwarded-Proto https; added in there and it should be good to go?

@dougwilson, maybe this is necropost, but please add this feature to documentation, there is no explanation for proxy_set_header X-Forwarded-Proto https; in nginx reverse proxy I found.

@BlackRoman strongly agree. This took three hours of my time to get to the bottom of..

If anyone who has had this issue wants to PR an addition to the docs that would make it much more likely that it will be added, I'm not sure how to document an issue I haven't had personally.

And to be clear: I would not like to add docs for how to configure NGINX or similar, as the configuration can vary by all kind of things (as can even be seen in this thread) and documenting how to configure 3-rd party systems is beyond the scope of the README in this module. At best, maybe the proxy section on expressjs.com, but that would more be up to the expressjs.com docs team. The configuration of NGINX and proxies is not specific to this module, especially since it uses the Express mechanism to read the values.

@dougwilson, maybe this is necropost, but please add this feature to documentation, there is no explanation for proxy_set_header X-Forwarded-Proto https; in nginx reverse proxy I found.

I'm not sure what you're asking, specifically, but the proxy feature is documented in multiple places in the readme currently: https://github.com/expressjs/session#proxy and https://github.com/expressjs/session#cookiesecure to name a couple. The expressjs.com docs has http://expressjs.com/en/guide/behind-proxies.html for how to use Express (and thus it's middlewares) behind proxies as well: http://expressjs.com/en/guide/behind-proxies.html

I working with express-server started as Azure Node web application behind IIS inside iframe of another domain :)))
The session cookie works fine if

a) app.set('trust proxy', true);
b) app.use( session({ <...another session oprions>, cookie: { secure: true, sameSite: 'none' } })

If with load balancer, can try this proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;

Was this page helpful?
0 / 5 - 0 ratings