Disable HTTP completely in Heroku
According to OWASP you should not redirect from HTTP to HTTPS. See https://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet#Rule_-REMOVED-_Do_Not_Perform_Redirects_from_Non-TLS_Page_to_TLS_Login_Page for more details.
I think the better solution would be to reject the request with a message letting the user know why. You should be able to do this in a middleware function. The actual status code you return is debatable but something like this should work:
app.use(function(req, res, next) { if(req.protocol !== 'https') { return res.status(403).send({message: 'SSL required'}); } // allow the request to continue next();});
You can test whether a request used https and then force a redirect using https if that is required (note the concern pointed out by @Ryan about redirecting and security). With Heroku, you can check the req headers' x-forwarded-proto
header to make sure it is https. Here is an example:
var express = require('express');var env = process.env.NODE_ENV || 'development';var forceSSL = function (req, res, next) { if (req.headers['x-forwarded-proto'] !== 'https') { return res.redirect(['https://', req.get('Host'), req.url].join('')); } return next();};var app = express();// in your app-level configurationsif (env === 'production') app.use(forceSSL);
Note: the Heroku load balancers are determining the x-forwarded-proto
header before it hits your app.
Also: get an SSL certificate if you are using a custom domain with Heroku