Я хотел бы заставить HTTPS и домен вершины (например, https://example.com) в моем приложении через конфигурацию nginx с использованием блоков местоположения. В настоящее время у меня есть следующий файл nginx_app.conf (который работает как с поддоменом apex, так и с субдоменом www, а также с http и https):
location / {
try_files $uri @rewriteapp;
}
location @rewriteapp {
rewrite ^(.*)$ /app.php/$1 last;
}
location ~ ^/(app|config)\.php(/|$) {
# fastcgi_pass directives go here...
}
Чтобы принудительно использовать домен вершины и https, я попытался использовать операторы if следующим образом, проверяя переменные $ scheme и $ host, но получаю сообщение об ошибке, что страница не перенаправляется должным образом. Я также добавлена директива HSTS.
location / {
if ($scheme = http) {
rewrite ^/(.*) https://$host/$1 permanent;
}
if ($host = www.example.com) {
rewrite ^/(.*) https://example.com/$1 permanent;
}
try_files $uri @rewriteapp;
}
location @rewriteapp {
rewrite ^(.*)$ /app.php/$1 last;
}
location ~ ^/(app|config)\.php(/|$) {
# fastcgi_pass directives go here...
add_header Strict-Transport-Security "max-age=86400";
}
Как правильно настроить http и домен вершины с конфигурацией nginx? Кроме того, я использую heroku (с DNSimple) для развертывания своего приложения, поэтому я хотел бы, чтобы работали оба следующих домена: https://example.herokuapp.com и https://example.com.
ОБНОВЛЕНИЕ: я попытался переместить операторы if за пределы блока местоположения в блок сервера по умолчанию (нажмите здесь), и измените перезаписи для возврата следующим образом, но это все равно не работает. Я по-прежнему получаю сообщение «Страница не перенаправляется должным образом» при запросе http и «Ошибка подключения» при запросе субдомена www.
if ($scheme = http) {
return 301 https://$host$request_uri;
}
if ($host = www.example.com) {
return 301 https://example.com$request_uri;
}
location / {
try_files $uri @rewriteapp;
}
location @rewriteapp {
rewrite ^(.*)$ /app.php/$1 last;
}
location ~ ^/(app|config)\.php(/|$) {
# fastcgi_pass directives go here...
add_header Strict-Transport-Security "max-age=86400";
}
1) Проблема здесь, вероятно, в балансировщике нагрузки Heroku. Когда в ваше приложение поступает запрос о посещении, он снова становится HTTP. Это просто внутренняя маршрутизация. Вы не можете протестировать против $scheme
. Но Heroku установил $http_x_forwarded_proto
заголовок для этих запросов.
if ($http_x_forwarded_proto != "https") {
return 301 https://$host$request_uri;
}
Источник: https://discussion.heroku.com/t/force-ssl-and-no-www-with-nginx-configuration/856
2а) Для перехода на no-www вы можете использовать это:
server {
listen <%= ENV["PORT"] %>;
server_name "~^www\.(.*)$";
return 301 https://$1$request_uri;
}
Для тестирования вы должны использовать 302 вместо 301, потому что браузер будет кэшировать 301 редирект.
Этот также перенаправит вас на https. Но только с субдомена www, поэтому вы должны сохранить указанное выше $http_x_forwarded_proto
перенаправить.
2b) Другой вариант - использовать серверный блок с субдоменом www и перенаправить его на домен без www, например:
server {
listen <%= ENV["PORT"] %>;
server_name www.example.com;
location / {
return 301 https://example.com$request_uri;
}
}
server {
listen <%= ENV["PORT"] %>;
server_name example.com;
location / {
try_files $uri $uri/ /index.html =404;
}
}
В <%= ENV["PORT"] %>
код исходит из сборочный пакет. На Heroku вы не можете слушать порт 80.
Лучше всего сделать 301 редирект.
server {
listen 80;
return 301 https://$host$request_uri;
}