-
-
Save nikmartin/5902176 to your computer and use it in GitHub Desktop.
Secure sessions are easy, but not very well documented. | |
Here's a recipe for secure sessions in Node.js when NginX is used as an SSL proxy: | |
The desired configuration for using NginX as an SSL proxy is to offload SSL processing | |
and to put a hardened web server in front of your Node.js application, like: | |
[NODE.JS APP] <- HTTP -> [NginX] <- HTTPS -> [PUBLIC INTERNET] <-> [CLIENT] | |
Edit for express 4.X and >: Express no longer uses Connect as its middleware framework, it implements its own now. | |
To do this, here's what you need to do: |
// 1. In your main App, setup up sessions: | |
app.enable('trust proxy'); | |
app.use(express.bodyParser()); | |
app.use(express.cookieParser()); | |
app.use(express.session({ | |
secret: 'Super Secret Password', | |
proxy: true, | |
key: 'session.sid', | |
cookie: {secure: true}, | |
//NEVER use in-memory store for production - I'm using mongoose/mongodb here | |
store: new sessionStore() | |
})); |
# 2. Configure nginx to do SSL and forward all the required headers that COnnect needs to do secure sessions: | |
server { | |
listen 443; | |
server_name localhost; | |
ssl on; | |
ssl_certificate /etc/nginx/nodeapp.crt; | |
ssl_certificate_key /etc/nginx/nodeapp.key; | |
ssl_session_timeout 5m; | |
ssl_protocols SSLv2 SSLv3 TLSv1; | |
ssl_ciphers HIGH:!aNULL:!MD5; | |
ssl_prefer_server_ciphers on; | |
location / { | |
# THESE ARE IMPORTANT | |
proxy_set_header X-Real-IP $remote_addr; | |
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |
# This is what tells Connect that your session can be considered secure, | |
# even though the protocol node.js sees is only HTTP: | |
proxy_set_header X-Forwarded-Proto $scheme; | |
proxy_set_header Host $http_host; | |
proxy_set_header X-NginX-Proxy true; | |
proxy_read_timeout 5m; | |
proxy_connect_timeout 5m; | |
proxy_pass http://nodeserver; | |
proxy_redirect off; | |
} | |
} |
Thanks! from 2019
This worked like a charm, after two days of fruitless research. Thanks a lot.
Thanks! 🙏
This gist was written 7 years ago, and this solution is STILL not well-documented, nor is it easy to find. I went as far as reading two books on Nginx, thinking I was simply misunderstanding how the damn thing worked, both of which still did not provide me with the right information. I even went to the extent of setting up my app directly with HTTPS, which defeated much of the benefit in using Nginx as a reverse proxy. After implementing this solution, I was able to set my app back to HTTP.
All of that to say THANK YOU. Thank you a million times over.
Wooow! Two days looking for this configuration. Thank you very much!
you are simply the best!
It 's indeed not well documentated. In my first Nginx-set up I had no idea. For me the 'app.enable('trust proxy');' was the life-changer. Thank you for sharing!
Hello, I came from 2022 to thank you and say that if you happen to spend a weekend in Brazil, in the region of São Paulo, send me an email and I will take you to the best steakhouse in the region as a thank you
Many thanks
Awesome, you're my hero I'll fight for you.
thank you very much! you save my project deadline!
Thank you, my good sir! Another deadline saved. May I too have as much good karma as you do.
Thank you boss !!! 🙌✨
Thank you!
this is great. it worked for me. i had to ensure that the nginx order of proxy headers was in line with your post. the headers needed to be above the proxy_pass pointer.
Thanks