Express.js redirect to HTTPS and send index.html

angularjs, express, heroku, javascript, node.js

Solution

Heroku terminates SSL connections at the load balancer level, so `req.secure` will never be true, because your connection to heroku's load balancer is not using SSL, thus creating an infinite redirect loop.

You have to check the `X-Forwarded-Proto` header instead:

if(req.headers["x-forwarded-proto"] === "https"){
  // OK, continue
  return next();
};
res.redirect('https://'+req.hostname+req.url);

Edit: you can also set `app.enable("trust proxy")` to have express check the headers automatically. See http://expressjs.com/guide/behind-proxies.html

Problem

I have a simple Express.js instance that's serving up static assets for a single page Angular app. I set up some middleware on the Express config so that index.html is returned for all routes and Angular can load from there. More recently, I set up SSL on Heroku and I want to make sure that all traffic that comes in from HTTP is redirected to HTTPS. I tried to combine the suggested solution from this post with what I have now, but end up in an endless redirect loop. In short, I need all traffic to be redirected from HTTP to HTTPS and the index.html file to be sent for all requests. What am I doing wrong here? ``` var gzippo = require('gzippo'); var express = require('express'); var morgan = require('morgan'); var app = express(); // set environment variables var env = app.get('env') || 'development'; app.use(morgan('dev')); // serve static assets app.use(gzippo.staticGzip("" + __dirname + "/dist")); app.use("/js", express.static(__dirname + "/dist/scripts")); app.use("/fonts", express.static(__dirname + "/fonts")); app.use("/img", express.static(__dirname + "/dist/assets/images")); app.use("/css", express.static(__dirname + "/dist/styles")); // Redirect all HTTP traffic to HTTPS function ensureSecure(req, res, next){ if(req.secure){ // OK, continue return next(); }; res.redirect('https://'+req.hostname+req.url); // handle port numbers if you need non defaults }; // Always send index.html function sendIndex(req, res, next) { res.sendfile('index.html', { root: __dirname + "/dist/"}); } // Handle environments if (env == 'production') { app.all('*', ensureSecure); } app.all('/*', sendIndex); // Start server app.listen(process.env.PORT || 5000); ```

Original source

Related problems