Автоматическое HTTPS-соединение / перенаправление с помощью node.js / express - PullRequest
148 голосов
/ 17 сентября 2011

Я пытался настроить HTTPS с проектом node.js, над которым я работаю. Я по существу следовал документации node.js для этого примера:

// curl -k https://localhost:8000/
var https = require('https');
var fs = require('fs');

var options = {
  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
};

https.createServer(options, function (req, res) {
  res.writeHead(200);
  res.end("hello world\n");
}).listen(8000);

Теперь, когда я делаю

curl -k https://localhost:8000/

Я получаю

hello world

как и ожидалось. Но если я сделаю

curl -k http://localhost:8000/

Я получаю

curl: (52) Empty reply from server

В ретроспективе кажется очевидным, что это будет работать таким образом, но в то же время люди, которые в конечном итоге посещают мой проект, не собираются вводить https : // yadayada, и я хочу, чтобы все трафик будет https с момента их попадания на сайт.

Как я могу заставить узел (и Express, так как это среда, которую я использую) передавать весь входящий трафик на https, независимо от того, был ли он указан? Я не смог найти никаких документов, которые касались этого. Или просто предполагается, что в производственной среде узел имеет что-то, что находится перед ним (например, nginx), который обрабатывает такой тип перенаправления?

Это мой первый опыт веб-разработки, поэтому, пожалуйста, прости мое невежество, если это что-то очевидное.

Ответы [ 16 ]

3 голосов
/ 20 октября 2017

Я использую решение, предложенное Basarat, но мне также нужно перезаписать порт, потому что у меня было 2 разных порта для протоколов HTTP и HTTPS.

res.writeHead(301, { "Location": "https://" + req.headers['host'].replace(http_port,https_port) + req.url });

Я предпочитаю также использовать нестандартный порт, чтобы запускать nodejs без прав root. Мне нравятся 8080 и 8443, потому что я много лет программирую на tomcat.

Мой полный файл стал

    var fs = require('fs');
var http = require('http');
var http_port    =   process.env.PORT || 8080; 
var app = require('express')();

// HTTPS definitions
var https = require('https');
var https_port    =   process.env.PORT_HTTPS || 8443; 
var options = {
   key  : fs.readFileSync('server.key'),
   cert : fs.readFileSync('server.crt')
};

app.get('/', function (req, res) {
   res.send('Hello World!');
});

https.createServer(options, app).listen(https_port, function () {
   console.log('Magic happens on port ' + https_port); 
});

// Redirect from http port to https
http.createServer(function (req, res) {
    res.writeHead(301, { "Location": "https://" + req.headers['host'].replace(http_port,https_port) + req.url });
    console.log("http request, will go to >> ");
    console.log("https://" + req.headers['host'].replace(http_port,https_port) + req.url );
    res.end();
}).listen(http_port);

Затем я использую iptable для переписывания трафика 80 и 443. Мои порты HTTP и HTTPS.

sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 8443
3 голосов
/ 03 ноября 2015
var express = require('express');
var app = express();

app.get('*',function (req, res) {
    res.redirect('https://<domain>' + req.url);
});

app.listen(80);

Это то, что мы используем, и это прекрасно работает!

3 голосов
/ 23 ноября 2012

вы можете использовать модуль "net" для прослушивания HTTP и HTTPS на одном и том же порту

2 голосов
/ 10 декабря 2016

Это сработало для меня:

app.use(function(req,res,next) {
    if(req.headers["x-forwarded-proto"] == "http") {
        res.redirect("https://[your url goes here]" + req.url, next);
    } else {
        return next();
    } 
});
1 голос
/ 29 февраля 2012

Вы можете создать 2 сервера Node.js - один для HTTP и HTTPS

Вы также можете определить функцию настройки, которую будут выполнять оба сервера, чтобы вам не приходилось писать многократно дублированный код.

Вот как я это сделал: (используя restify.js, но должен работать для express.js или для самого узла)

http://qugstart.com/blog/node-js/node-js-restify-server-with-both-http-and-https/

0 голосов

Это сработало для меня:

/* Headers */
require('./security/Headers/HeadersOptions').Headers(app);

/* Server */
const ssl = {
    key: fs.readFileSync('security/ssl/cert.key'),
    cert: fs.readFileSync('security/ssl/cert.pem')
};
//https server
https.createServer(ssl, app).listen(443, '192.168.1.2' && 443, '127.0.0.1');
//http server
app.listen(80, '192.168.1.2' && 80, '127.0.0.1');
app.use(function(req, res, next) {
    if(req.secure){
        next();
    }else{
        res.redirect('https://' + req.headers.host + req.url);
    }
});

Рекомендуем добавить заголовки перед перенаправлением на https

Теперь, когда вы делаете:

curl http://127.0.0.1 --include

Вы получаете:

HTTP/1.1 302 Found
//
Location: https://127.0.0.1/
Vary: Accept
Content-Type: text/plain; charset=utf-8
Content-Length: 40
Date: Thu, 04 Jul 2019 09:57:34 GMT
Connection: keep-alive

Found. Redirecting to https://127.0.0.1/

Я использую экспресс 4.17.1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...