Redirecting to HTTPS in Node.js on Azure Websites
If you’ve got a node.js website running in Azure Websites, you get SSL by default, or if you bring your own domain name, you can easily set up SSL with your own certificate.
The default behaviour is that the website serves both HTTP and HTTPS requests, but what if you want to switch users automatically over to HTTPS (i.e. disable HTTP).
The normal approach when using express.js is to use some middleware which detects the protocol and redirects accordingly. Like this:
// this doesn't work in Azure Websites function requireHTTPS(req, res, next) { if (!req.secure) { return res.redirect('https://' + req.get('host') + req.url); } next(); } app.use(requireHTTPS);
req.secure
is just a shorthand for checking the protocol of the incoming request. However, in Azure websites your server is fronted by a web server running ARR, which does the SSL termination. This means the request you see will always be HTTP. The above code samples creates a redirect loop as the middleware continues to redirect to HTTPS, as it keeps seeing HTTP.
Fortunately ARR adds some additional headers to the request. These are:
cookie: ARRAffinity=71111a2979a8796b0cc6860d7f98cb7519aaea861cc96f15896edbb25a259064 host: XYZ.azurewebsites.net max-forwards: 10 x-liveupgrade: 1 x-arr-log-id: 7cffa211-21f6-42c2-8b7d-e9eacac8adc8 disguised-host: XYZ.azurewebsites.net x-site-deployment-id: XYZ x-original-url: /url x-forwarded-for: 212.69.41.154:4219 x-arr-ssl: 2048|128|DC=com, DC=microsoft, DC=corp, DC=redmond, CN=MSIT Machine Auth CA 2|C=US, S=WA, L=Redmond, O=Microsoft, OU=OrganizationName, CN=*.azurewebsites.net
The x-arr-ssl
header is only added for HTTPS requests, so we can use this header to determine whether it’s a HTTP or HTTPS request.
function requireHTTPS(req, res, next) { if (!req.get('x-arr-ssl')) { return res.redirect('https://' + req.get('host') + req.url); } next(); } app.use(requireHTTPS);
You could go one better, and only do the upgrade if you’re running in Azure, which means you can run your site in plain HTTP in your local environment:
function requireHTTPS(req, res, next) { if (req.get('x-site-deployment-id') && !req.get('x-arr-ssl')) { return res.redirect('https://' + req.get('host') + req.url); } next(); } app.use(requireHTTPS);
stpdev 4:07 pm on September 23, 2015 Permalink | Log in to Reply
Azure has it’s own method of handling HTTPS redirection. NodeJS apps in Azure are still manage through IIS runtimes.
Their recommended approach is to add rewrite rules to the web.config.
The web.config is only created after an initial deployment (easiest way to get it generated for all the node handling). You grab it via FTP credentials set up through the portal and simply add the rewrite rule to the existing rules in place.
Once its there and you include it in the root dir of your deployed app, azure will use it.
stpdev 4:10 pm on September 23, 2015 Permalink | Log in to Reply
Here’s the simple rewrite rule: https://gist.github.com/tstpierre/afec7eb409aebe0bf3d1