Próbowałem skonfigurować protokół HTTPS z projektem node.js, nad którym pracuję. Zasadniczo postępowałem zgodnie z dokumentacją node.js dla tego przykładu:
// 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);
Teraz, kiedy to zrobię
curl -k https://localhost:8000/
dostaję
hello world
zgodnie z oczekiwaniami. Ale jeśli to zrobię
curl -k http://localhost:8000/
dostaję
curl: (52) Empty reply from server
Z perspektywy czasu wydaje się to oczywiste, że to zadziała w ten sposób, ale jednocześnie ludzie, którzy ostatecznie odwiedzą mój projekt, nie będą wpisywać https : // yadayada, a ja chcę, aby cały ruch był https od momentu, w którym trafią Strona.
Jak mogę sprawić, aby węzeł (i Express, ponieważ jest to platforma, której używam), przekazywał cały ruch przychodzący do https, niezależnie od tego, czy został określony, czy nie? Nie udało mi się znaleźć żadnej dokumentacji, która dotyczyłaby tego. A może po prostu zakłada się, że w środowisku produkcyjnym node ma coś, co znajduje się przed nim (np. Nginx), co obsługuje tego rodzaju przekierowanie?
To moja pierwsza przygoda z tworzeniem stron internetowych, więc proszę wybacz moją ignorancję, jeśli jest to coś oczywistego.
Odpowiedzi:
Ryan, dzięki za wskazanie mi właściwego kierunku. Uzupełniłem twoją odpowiedź (akapit drugi) trochę kodem i działa. W tym scenariuszu te fragmenty kodu są umieszczane w mojej aplikacji ekspresowej:
Serwer https express nasłuchuje ATM na 3000. Ustawiłem te reguły iptables, aby węzeł nie musiał działać jako root:
Wszystko razem działa dokładnie tak, jak chciałem.
źródło
Error 310 (net::ERR_TOO_MANY_REDIRECTS): There were too many redirects
if(!req.secure){}
if(req.protocol==='http')
oświadczeniaJeśli podążasz za konwencjonalnymi portami, ponieważ HTTP domyślnie próbuje portu 80, a HTTPS domyślnie próbuje portu 443, możesz po prostu mieć dwa serwery na tej samej maszynie: Oto kod:
Testuj za pomocą https:
Z http:
Więcej szczegółów: Nodejs HTTP i HTTPS przez ten sam port
źródło
res.writeHead(301, etc.)
będzie działać poprawnie tylko dla wywołań GET, ponieważ301
nie mówi klientowi, aby używał tej samej metody. Jeśli chcesz zachować używaną metodę (i wszystkie inne parametry), musisz użyćres.writeHead(307, etc.)
. A jeśli nadal nie działa, być może trzeba będzie wykonać pewne proxy. Źródło: http://stackoverflow.com/a/17612942/1876359Dzięki temu facetowi: https://www.tonyerwin.com/2014/09/redirecting-http-to-https-with-nodejs.html
źródło
app.enable('trust proxy');
app.get('X-Forwarded-Proto') != 'http'
zamiastreq.secure
aws.amazon.com/premiumsupport/knowledge-center/ ...Dzięki Nginx możesz skorzystać z nagłówka „x-forwarded-proto”:
źródło
app.enable('trust proxy');
: „Wskazuje, że aplikacja znajduje się za przednim serwerem proxy i aby użyć nagłówków X-Forwarded- * do określenia połączenia i adresu IP klienta”. expressjs.com/en/4x/api.html#app.setOd 0.4.12 nie mamy prawdziwego, czystego sposobu nasłuchiwania HTTP i HTTPS na tym samym porcie przy użyciu serwerów HTTP / HTTPS węzła.
Niektórzy ludzie rozwiązali ten problem, mając serwer HTTPS Node (działa to również z Express.js) nasłuchujący 443 (lub jakiś inny port), a także mając mały serwer http, który łączy się z 80 i przekierowuje użytkowników do bezpiecznego portu.
Jeśli absolutnie musisz mieć możliwość obsługi obu protokołów na jednym porcie, musisz umieścić nginx, lighttpd, apache lub inny serwer WWW na tym porcie i działać jako zwrotne proxy dla Node.
źródło
Możesz użyć modułu express-force-https :
npm install --save express-force-https
źródło
app
. (patrz odpowiedź )Korzystam z rozwiązania zaproponowanego przez Basarata, ale muszę też nadpisać port, ponieważ miałem 2 różne porty dla protokołów HTTP i HTTPS.
Wolę również używać niestandardowego portu, aby uruchomić nodejs bez uprawnień roota. Lubię 8080 i 8443, ponieważ pochodzę z wielu lat programowania na tomcat.
Mój kompletny plik to
Następnie używam iptable do formułowania ruchu 80 i 443 na moich portach HTTP i HTTPS.
źródło
Ta odpowiedź musi zostać zaktualizowana, aby działała z Express 4.0. Oto jak uruchomiłem oddzielny serwer http:
źródło
Jeśli Twoja aplikacja znajduje się za zaufanym proxy (np. AWS ELB lub poprawnie skonfigurowanym nginx), ten kod powinien działać:
Uwagi:
źródło
Uważam, że req.protocol działa, gdy używam express (nie testowałem bez, ale podejrzewam, że działa). przy użyciu bieżącego węzła 0.10.22 z wyrażeniem 3.4.3
źródło
Większość odpowiedzi sugeruje użycie nagłówka req.headers.host.
Nagłówek hosta jest wymagany przez HTTP 1.1, ale w rzeczywistości jest opcjonalny, ponieważ nagłówek może nie zostać wysłany przez klienta HTTP, a węzeł / express zaakceptuje to żądanie.
Możesz zapytać: który klient HTTP (np. Przeglądarka) może wysłać żądanie bez tego nagłówka? Protokół HTTP jest bardzo trywialny. Możesz utworzyć żądanie HTTP w kilku wierszach kodu, aby nie wysyłać nagłówka hosta, a jeśli za każdym razem, gdy otrzymasz zniekształcone żądanie, zgłosisz wyjątek i w zależności od tego, jak obsłużysz takie wyjątki, może to spowodować wyłączenie serwera.
Dlatego zawsze sprawdzaj poprawność wszystkich danych wejściowych . To nie jest paranoja, otrzymałem żądania bez nagłówka hosta w mojej usłudze.
Nigdy też nie traktuj adresów URL jako ciągów . Użyj modułu node url, aby zmodyfikować określone części ciągu. Traktowanie adresów URL jako ciągów znaków można wykorzystać na wiele różnych sposobów. Nie rób tego.
źródło
Tego używamy i działa świetnie!
źródło
możesz użyć modułu "net" do nasłuchiwania HTTP i HTTPS na tym samym porcie
źródło
To zadziałało dla mnie:
źródło
Możesz utworzyć instancję 2 serwerów Node.js - jeden dla HTTP i HTTPS
Możesz także zdefiniować funkcję konfiguracyjną, którą będą wykonywać oba serwery, dzięki czemu nie musisz pisać zbyt wielu zduplikowanych kodów.
Oto sposób, w jaki to zrobiłem: (używając restify.js, ale powinno działać dla express.js lub samego węzła)
http://qugstart.com/blog/node-js/node-js-restify-server-with-both-http-and-https/
źródło
To zadziałało dla mnie:
Zalecamy dodanie nagłówków przed przekierowaniem do https
Teraz, kiedy to zrobisz:
Dostajesz:
Używam express 4.17.1
źródło