Skip to content

Instantly share code, notes, and snippets.

@nikmartin
Last active November 10, 2023 21:05
Star You must be signed in to star a gist
Embed
What would you like to do?
Secure sessions with Node.js, Express.js, and NginX as an SSL Proxy
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;
}
}
@chinmay185
Copy link

You're a life saver!

@th3o6a1d
Copy link

This just made my day!

@tiblu
Copy link

tiblu commented Jun 3, 2015

Thanks for sharing!

@twogood
Copy link

twogood commented Feb 23, 2016

Thanks a bunch! I had everything correct except proxy_redirect off; (I had proxy_redirect default) and that didn't work for my Google OAuth2 login!

@tsabolov
Copy link

Thank you for this recipe! In my case proxy_set_header X-Forwarded-Proto $scheme; was absent.

@stlyz3
Copy link

stlyz3 commented May 3, 2016

An absolute godsend! Thanks very much!

@albacoretuna
Copy link

I was bitten by lack of this as well: proxy_set_header X-Forwarded-Proto $scheme;

@ralphv
Copy link

ralphv commented Dec 2, 2016

for AWS elastic load balancer offloading the SSL, I had to change the $scheme to explicitly say 'https', because even at the nginx level, the scheme was still http.

@swapnil001
Copy link

I have followed the same above method still getting "failed: Error during WebSocket handshake: Unexpected response code: 301". Also using socket io redis for multi processors. Any idea how to fix this issue?

@luisfermp19
Copy link

Hi Guys!

Good morning/evening/night for all.

First, thank you, you have assisted to me to make a correct configuration to attend https request. But seeing this, me a small doubt arises, where is the nginx-ssl.conf configuration file?

Thx for all!

@mouradhamoud
Copy link

Thanks!!

@pawelrychlik
Copy link

Thanks a million! 🙏

@tonyamos
Copy link

Let me add another THANK YOU!!

@labmorales
Copy link

👍 Thanks!

@robba86
Copy link

robba86 commented Feb 1, 2018

Awesome, thanks!

@anandve
Copy link

anandve commented Sep 25, 2018

Thanks!

@grumpitect
Copy link

Thanks

@tsq
Copy link

tsq commented Apr 23, 2019

Thanks! from 2019

@sbadri2001
Copy link

This worked like a charm, after two days of fruitless research. Thanks a lot.

@Ujoy7851
Copy link

Ujoy7851 commented Sep 2, 2020

Thanks! 🙏

@nonsensetwice
Copy link

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.

@frames75
Copy link

frames75 commented Oct 7, 2020

Wooow! Two days looking for this configuration. Thank you very much!

@sim-17
Copy link

sim-17 commented Oct 12, 2020

you are simply the best!

@tichel
Copy link

tichel commented Feb 5, 2021

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!

@ThiagoWenemy
Copy link

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

@AnttiVirtanen
Copy link

Many thanks

@El-khamisi
Copy link

Awesome, you're my hero I'll fight for you.

@simonlopezs
Copy link

thank you very much! you save my project deadline!

@MadhavShroff
Copy link

Thank you, my good sir! Another deadline saved. May I too have as much good karma as you do.

@rohitrikhi
Copy link

Thank you boss !!! 🙌✨

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment