Я хотел бы вызвать HTTPS и домен вершины (например, https://example.com) в моем приложении через nginx конфигурацию с помощью блоков местоположения. У меня в настоящее время есть следующий nginx_app.conf файл (который работает и с вершиной и с 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";
}
Лучшим способом является перенаправление 301.
server {
listen 80;
return 301 https://$host$request_uri;
}
1) Вероятно, проблема здесь в балансировщике нагрузки Heroku. Когда запрос на посещение приходит в ваше приложение, это снова HTTP. Это просто внутренняя маршрутизация. Вы не можете протестировать на $scheme
. Но Heroku установил $http_x_forwarded_proto
заголовок на эти запросы.
if ($http_x_forwarded_proto != "https") {
return 301 https://$host$request_uri;
}
Source: https://discussion.heroku.com/t/force-ssl-and-no-www-with-nginx-configuration/856
2a) Для перенаправления на 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"] %>
происходит из buildpack. На Heroku нельзя слушать порт 80.