Переадресация HTTPS работает только при перезагрузке страницы
Я установил SSL-сертификат на своей странице, который запускает приложение Node.js + Express, настроил сервер Express всегда на перенаправление на HTTP-сервер, и все работает нормально, за исключением того, что перенаправление https работает только тогда, когда страница перезагружается или когда клавиша Enter снова нажата. Я записал gif, чтобы показать, что происходит:
http://recordit.co/uBiW3bcQCM
И вот моя экспресс-конфигурация.
var express = require('express');
var path = require('path');
var serveStatic = require('serve-static');
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();
};
app = express();
app.use(serveStatic(__dirname));
if(process.env.NODE_ENV === 'production') {
app.use(forceSsl);
}
app.all('/*', function(req, res) {
res.sendfile('index.html');
});
var port = process.env.PORT || 5000;
app.listen(port);
console.log('server started '+ port);
Мое приложение работает на Heroku. Может ли кто-нибудь помочь мне узнать, что происходит?
Спасибо заранее.
Ответы
Ответ 1
Я думаю, что ваш сервер отправляет контент перед отправкой заголовков перенаправления.
Если вы меняете:
app.use(serveStatic(__dirname));
app.use(forceSsl);
для
app.use(forceSsl);
app.use(serveStatic(__dirname));
Кажется, он работает намного лучше!
Причина, по которой ваш браузер выполнял перенаправление при перезагрузке/вводе, неясен для меня, поскольку я не мог воспроизвести поведение. В FF я никогда не перенаправлялся.
Возможно, это связано с тем, что заголовки запроса различаются, например HEAD, вместо GET или что-то еще. Я не мог больше исследовать это, использовать Wireshark или Burpsuite, чтобы точно знать, что происходит, если это все еще имеет значение...
Ответ 2
Это redirectToHTTPS() промежуточное программное обеспечение должно работать на вас. Он перенаправляется на сайт https, даже если пользователь не предоставляет префикс. Добавьте X-Forwarded-Port
для идентификации порта, используемого для сайта https.
function redirectToHTTPS () {
return function middlewareRedirectToHTTPS (req, res, next) {
const isNotSecure = (!req.get('x-forwarded-port') && req.protocol !== 'https') ||
parseInt(req.get('x-forwarded-port'), 10) !== 443
if (isNotSecure) {
return res.redirect('https://' + req.get('host') + req.url)
}
next()
}
}