简体   繁体   中英

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;

As it turns out, I simply had to reorder my app.use statements — calling the redirect before serving the static files.

Additionally, in order for this to work on IE/Edge, 'https://' needed to be moved outside of path.join (join removes the second forward slash, and although all other major browsers will handle it properly, IE doesn't like it).

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();
  return res.redirect(301, `https://${join(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;

The most obvious issue in your code is that HTTPS is served from port 443. Besides that looks like outdated code. Why not use a recent version of Express? If you look at the example for HTTPS they give here its pretty different from what you wrote: http://expressjs.com/en/api.html search for 'HTTPS'

var express = require('express');
var https = require('https');
var http = require('http');
var app = express();

http.createServer(app).listen(80);
https.createServer(options, app).listen(443);

When I have used node.js as a proxy in the past, the way we got unsecure connections to proxy to secure was as follows, amended to match your code:

const httpsPort = process.env.HTTPS_PORT;

app.use(function(req, res, next) {
    if (req.secure) {
        return next();
    }
    res.redirect(301, ['https://', req.hostname, ':', httpsPort, '/', req.url].join('');
}

Where httpsPort is whatever the port your standard https connections will go through. Where process.env.HTTPS_PORT would get the environment variable for the https port (Standard is 443). You could replace this with whatever you want to get the port.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM