Heroku NodeJS http to https ssl принудительное redirect
У меня есть приложение вверх и работает на heroku с выражением на узле с https. Как определить протокол для перенаправления https с помощью nodejs на heroku?
Мое приложение – это просто простой HTTP-сервер, он еще не осознает, что герой отправляет его https-запросы:
/* Heroku provides the port they want you on in this environment variable (hint: it's not 80) */ app.listen(process.env.PORT || 3000);
- rails: 3 Приостановить регистрацию Цепь фильтра остановлена как: require_no_authentication, обработанная или перенаправленная
- http до https через .htaccess
- Как получить URL-адрес реферера в действии ASP.NET MVC?
- Правило ReWrite для добавления расширения .html
- Как перенаправить stderr в null в cmd.exe
- Как перенаправить внешний URL в Angular2?
- Как выполнять динамические переадресации URL в Struts 2?
- .htaccess redirect без изменения адресной строки
- URL-fragment и 302 перенаправления
- Spring Boot перенаправляет HTTP на HTTPS
- htaccess перенаправляет для не-www как http, так и https
- Необходимо перенаправить весь трафик на https
- .htaccess перенаправить www на не-www с SSL / HTTPS
На сегодняшний день, 10 октября 2014 года , с использованием кедра Heroku Cedar и ExpressJS ~ 3.4.4 , здесь приведен рабочий набор кода.
Главное здесь помнить, что мы развертываемся в Героку. Терминал SSL происходит на балансировщике нагрузки, прежде чем зашифрованный трафик достигнет вашего узла. Можно проверить, использовался ли https для запроса с помощью req.headers [‘x-forwarded-proto’] === ‘https’ .
Нам не нужно беспокоиться о наличии локальных сертификатов SSL внутри приложения и т. Д., Как вы можете, если хостинг в других средах. Тем не менее, вы должны получить надстройку SSL, применяемую через надстройки Heroku, если вы используете свой собственный сертификат, поддомены и т. Д.
Затем просто добавьте следующее, чтобы сделать redirect от чего-либо, кроме HTTPS, до HTTPS. Это очень близко к принятому ответу выше, но:
- Обеспечивает использование «app.use» (для всех действий, а не только для получения)
- Явно нарушает логику forceSsl в объявленной функции
- Не использует «*» с «app.use» – это действительно провалилось, когда я его протестировал.
- Здесь я хочу только SSL в производстве. (Изменить в соответствии с вашими потребностями)
Код:
var express = require('express'), env = process.env.NODE_ENV || 'development'; 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.configure(function () { if (env === 'production') { app.use(forceSsl); } // other configurations etc for express go here... }
Примечание для пользователей SailsJS (0.10.x). Вы можете просто создать политику (enforceSsl.js) внутри api / политик:
module.exports = function (req, res, next) { 'use strict'; if ((req.headers['x-forwarded-proto'] !== 'https') && (process.env.NODE_ENV === 'production')) { return res.redirect([ 'https://', req.get('Host'), req.url ].join('')); } else { next(); } };
Затем ссылку из config / policy.js вместе с любыми другими политиками, например:
‘*’: [‘authenticated’, ‘enforceSsl’]
Ответ заключается в том, чтобы использовать заголовок ‘x-forwarded-proto’, который Heroku проходит вперед, поскольку он делает это proxy thingamabob. (сторона примечания: они также передают несколько других x-переменных, которые могут быть удобными, проверьте их ).
Мой код:
/* At the top, with other redirect methods before other routes */ app.get('*',function(req,res,next){ if(req.headers['x-forwarded-proto']!='https') res.redirect('https://mypreferreddomain.com'+req.url) else next() /* Continue to other routes if we're not redirecting */ })
Спасибо, Брэндон, просто ждал этой 6-часовой задержки, которая не позволила бы мне ответить на мой собственный вопрос.
В принятом ответе есть жесткий код в нем, что не слишком хорошо, если у вас есть тот же код на нескольких доменах (например: dev-yourapp.com, test-yourapp.com, yourapp.com).
Используйте это вместо этого:
/* Redirect http to https */ app.get('*', function(req,res,next) { if(req.headers['x-forwarded-proto'] != 'https' && process.env.NODE_ENV === 'production') res.redirect('https://'+req.hostname+req.url) else next() /* Continue to other routes if we're not redirecting */ });
https://blog.mako.ai/2016/03/30/redirect-http-to-https-on-heroku-and-node-generally/
Я написал небольшой модуль узла, который обеспечивает SSL для express-проектов. Он работает как в стандартных ситуациях, так и в случае обратных прокси (Heroku, nodejitsu и т. Д.),
Если вы хотите протестировать заголовок x-forwarded-proto
на своем локальном хосте, вы можете использовать nginx для установки vhost-файла, который проксирует все запросы к вашему узловому приложению. Ваш конфигурационный файл nginx vhost может выглядеть так:
Nginx
server { listen 80; listen 443; server_name dummy.com; ssl on; ssl_certificate /absolute/path/to/public.pem; ssl_certificate_key /absolute/path/to/private.pem; access_log /var/log/nginx/dummy-access.log; error_log /var/log/nginx/dummy-error.log debug; # node location / { proxy_pass http://127.0.0.1:3000/; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
Важными битами здесь являются то, что вы проксируете все запросы на localhost port 3000 (это приложение для вашего узла работает), и вы настраиваете кучу заголовков, включая X-Forwarded-Proto
Затем в вашем приложении обнаружите этот заголовок как обычно
express
var app = express() .use(function (req, res, next) { if (req.header('x-forwarded-proto') == 'http') { res.redirect(301, 'https://' + 'dummy.com' + req.url) return } next() })
Коа
var app = koa() app.use(function* (next) { if (this.request.headers['x-forwarded-proto'] == 'http') { this.response.redirect('https://' + 'dummy.com' + this.request.url) return } yield next })
Хосты
Наконец, вы должны добавить эту строку в файл hosts
127.0.0.1 dummy.com
Если вы используете cloudflare.com как CDN в сочетании с heroku, вы можете легко включить автоматическую переадресацию ssl в cloudflare следующим образом:
-
Войдите и войдите в свою панель инструментов.
-
Выбор правил страницы
- Добавьте свой домен, например http://www.example.com, и всегда переключайте https на
Пользователи Loopback могут использовать слегка адаптированную версию решения arcseldon в качестве промежуточного ПО:
сервера / ПО промежуточного слоя / forcessl.js
module.exports = function() { return function forceSSL(req, res, next) { var FORCE_HTTPS = process.env.FORCE_HTTPS || false; if (req.headers['x-forwarded-proto'] !== 'https' && FORCE_HTTPS) { return res.redirect(['https://', req.get('Host'), req.url].join('')); } next(); }; };
Сервер / server.js
var forceSSL = require('./middleware/forcessl.js'); app.use(forceSSL());
Вы должны взглянуть на heroku-ssl-redirect . Отлично работает!
var sslRedirect = require('heroku-ssl-redirect'); var express = require('express'); var app = express(); // enable ssl redirect app.use(sslRedirect()); app.get('/', function(req, res){ res.send('hello world'); }); app.listen(3000);
Проверка протокола в заголовке X-Forwarded-Proto отлично работает на Heroku, как указал Дерек. Для чего это стоит, вот суть промежуточного программного обеспечения Express, которое я использую, и его соответствующий тест.
app.all('*',function(req,res,next){ if(req.headers['x-forwarded-proto']!='https') { res.redirect(`https://${req.get('host')}`+req.url); } else { next(); /* Continue to other routes if we're not redirecting */ } });
Более конкретный способ сделать это.
app.enable('trust proxy'); app.use('*', (req, res, next) => { if (req.secure) { return next(); } res.redirect(`https://${req.hostname}${req.url}`); });