我一直在挠头,因为所有的论坛都说,以下简单的代码应该工作,redirect所有stream量从HTTPS到HTTP,除了一个位置( Nginx的:在一个path上强制SSL,其他人不SSL ),但在我的情况它没有按预期工作
这是Magento网站有以下nginxconfiguration
upstream examplecombackend { server unix:/var/run/php-fcgi-examplecom.sock; } server { listen 111.11.111.111:80; server_name example.com *.example.com; access_log /home/www/vhosts/example.com/logs/access.log; error_log /home/www/vhosts/example.com/logs/error.log; root /home/www/vhosts/example.com/httpdocs; location / { index index.html index.php; try_files $uri $uri/ @handler; expires 30d; } location /checkout/ { rewrite ^ https://$host$request_uri? permanent; } location @handler { rewrite / /index.php; } location ~ .php/ { rewrite ^(.*.php)/ $1 last; } location ~ .php$ { if (!-e $request_filename) { rewrite / /index.php last; } expires off; fastcgi_pass examplecombackend; fastcgi_param HTTPS $fastcgi_https; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } server { listen 111.11.111.111:443 ssl; ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; server_name example.com *.example.com; root /home/www/vhosts/example.com/httpdocs; location / { rewrite ^ http://$host$request_uri? permanent; } location /checkout/ { } }
现在,当我进入SSL https://example.com/时,它正确地转发到非SSL http://example.com/,但如果我去https://example.com/checkout它说
404 Not Found nginx/1.8.1
不知道我在这里失踪….
首先,我不会自己做这样的configuration。 在同一个网站上混合使用http
和https
会使https
安全性变弱,并使您的网站遭受中间人攻击。
但是,如果你真的想要设置这样的事情,这里应该是一个工作configuration。
您configuration中的主要问题是您的/checkout
URI缺lessPHP的定义。
我会做这样的configuration。 这还包含对您的configuration的优化:
upstream examplecombackend { server unix:/var/run/php-fcgi-examplecom.sock; } server { listen 111.11.111.111:80; server_name example.com *.example.com; access_log /home/www/vhosts/example.com/logs/access.log; error_log /home/www/vhosts/example.com/logs/error.log; root /home/www/vhosts/example.com/httpdocs; location / { index index.html index.php; try_files $uri $uri/ /index.php; expires 30d; } location /checkout { rewrite ^ https://$host$request_uri? permanent; } location ~ (.+\.php)/ { rewrite ^ $1 last; } location ~ \.php$ { expires off; fastcgi_pass examplecombackend; fastcgi_param HTTPS $fastcgi_https; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } server { listen 111.11.111.111:443 ssl; ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; server_name example.com *.example.com; root /home/www/vhosts/example.com/httpdocs; location /checkout { rewrite ^ /index.php; } location ~ \.php$ { expires off; fastcgi_pass examplecombackend; fastcgi_param HTTPS $fastcgi_https; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } location / { rewrite ^ http://$host$request_uri? permanent; } }
我做的更改:
location / { index index.html index.php; try_files $uri $uri/ /index.php; expires 30d; }
我删除了@handler
位置,因为它与index.php
是try_files
指令的最后一个元素相同。
location ~ .php/ { rewrite ^(.*.php)/ $1 last; }
我改变了正则expression式的捕获发生在location
级别,因此在匹配这个位置的每个请求上只有一个正则expression式的匹配less了,因为我们可以使用简单的^
作为rewrite
指令中的匹配条件。
location ~ \.php$ { if (!-e $request_filename) { rewrite / /index.php last; }
我添加了反斜杠转义location
正则expression式的条件,因为没有反斜杠它将匹配例如/path/to/aphp
,因为.
自己匹配任何字符。
我还从块中删除了上面显示的if
testing,因为之前在try_files
指令中已经发生过相同的testing。
最后,解决您的实际问题:
在你的https server
块,我改变了这样的location
块:
location /checkout { rewrite ^ /index.php; } location ~ \.php$ { expires off; fastcgi_pass examplecombackend; fastcgi_param HTTPS $fastcgi_https; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }
所以, location /checkout
块告诉nginx重写所有的请求到/index.php
,就像在http
服务器块一样。 此外,PHP处理location
与http
块中的location
相同。
但是,Magento创build的链接仍然可能存在问题,并且请求会在http
和https
之间redirect。 Cookie安全设置是一件可能导致问题的事情。
试试这个小小的变化。 〜*应该告诉Nginx不区分大小写匹配任何带有/ checkout /的URL,而不仅仅是准确的URL / checkout /。
我有点生疏,我不记得确切的位置匹配顺序和语法,但值得一试。
location ~* /checkout/ {
有条件的重写可能有助于你的情况:
server { listen 111.11.111.111:80; listen 111.11.111.111:443 ssl; ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; server_name example.com *.example.com; access_log /home/www/vhosts/example.com/logs/access.log; error_log /home/www/vhosts/example.com/logs/error.log; root /home/www/vhosts/example.com/httpdocs; location / { if ($scheme = "https") { return 301 http://$server_name$request_uri; break; } index index.html index.php; try_files $uri $uri/ @handler; expires 30d; } location /checkout/ { if ($scheme = "http") { return 301 https://$server_name$request_uri; break; } } location @handler { rewrite / /index.php; } location ~ .php/ { rewrite ^(.*.php)/ $1 last; } location ~ .php$ { if (!-e $request_filename) { rewrite / /index.php last; } expires off; fastcgi_pass examplecombackend; fastcgi_param HTTPS $fastcgi_https; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }