jabacchetta jabacchetta - 1 month ago 19
Javascript Question

Redirect to HTTPS with Node/Express on Elastic Beanstalk

I'm trying to get a site to force HTTPS (redirect from HTTP). We've got HTTPS set up via AWS Elastic Beanstalk. The problem is that, currently, both HTTP and HTTPS can be used.

After reading through a few posts, including this one, the code below is what I came up with. Unfortunately this isn't working.

What am I missing?

import express from 'express';
import { join } from 'path';

const app = express();
const buildPath = join(`${__dirname}/../build`);
const enforceHTTPS = (req, res, next) => {
if (req.headers['x-forwarded-proto'] === 'https') return next();
else return res.redirect(301, join(`https://${req.hostname}${req.url}`));
};

app.use(express.static(buildPath));
app.use(enforceHTTPS);
app.get('*', (req, res) => res.sendFile(`${buildPath}/index.html`));
app.listen(process.env.PORT || 3000, () => console.log('Server running on port 3000!'));

export default app;

Answer

As it turns out, I simply had to reorder my app.use statements — calling the redirect before serving the static files. I should have paid more attention to the comments in the exact post that I referenced (they had the same issue).

Here's a working example:

import express from 'express';
import { join } from 'path';

const app = express();
const buildPath = join(`${__dirname}/../build`);
const enforceHTTPS = (req, res, next) => {
  if (req.headers['x-forwarded-proto'] === 'https') return next();
  else return res.redirect(301, join(`https://${req.hostname}${req.url}`));
};

app.use(enforceHTTPS);
app.use(express.static(buildPath));
app.get('*', (req, res) => res.sendFile(`${buildPath}/index.html`));
app.listen(process.env.PORT || 3000, () => console.log('Server running on port 3000!'));

export default app;