简体   繁体   English

Https导致重定向循环?

[英]Https causing redirect loop?

I am using code igniter, our server is behind some funky config. 我正在使用代码点火器,我们的服务器背后有一些时髦的配置。

I want certian pages to be behind https, certian pages to be behind http, and others I don't care about. 我希望certian页面落后于https,certian页面落后于http,以及其他我不关心的页面。

So below is my setup, 以下是我的设置,

  • If I go to http://test.example.com (which has a call to disable_ssl() ) the page loads fine 如果我去http://test.example.com (它调用disable_ssl() )页面加载正常
  • If I go to https://test.example.com/login (which has a call to require_ssl() ) the page loads fine. 如果我转到https://test.example.com/login (调用require_ssl() )页面加载正常。
  • If I go the http://test.example.com/login I get redirected to the https version. 如果我去http://test.example.com/login我会被重定向到https版本。 which is good. 这很好。
  • If I go to https://test.example.com then I get hit with a redirect loop... For some reason the header keeps getting set to https instead of http , even though I explicitly write http . 如果我去https://test.example.com然后我被重定向循环命中...由于某种原因,标题不断设置为https而不是http ,即使我明确写了http

My $_SERVER array on an http request looks like looks like http请求上的$_SERVER数组看起来像

Array
(
    [REDIRECT_STATUS] => 200
    [HTTP_HOST] => test.example.com:80
    [HTTP_X_REAL_IP] => 119.224.22.142
    [HTTP_X_FORWARDED_FOR] => 119.224.22.142
    [HTTP_X_URL_SCHEME] => http
    [HTTP_CONNECTION] => close
    [HTTP_CACHE_CONTROL] => max-age=0
    [HTTP_USER_AGENT] => Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.100 Safari/534.30
    [HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8
    [HTTP_ACCEPT_ENCODING] => gzip,deflate,sdch
    [HTTP_ACCEPT_LANGUAGE] => en-US,en;q=0.8,en-NZ;q=0.6
    [HTTP_ACCEPT_CHARSET] => ISO-8859-1,utf-8;q=0.7,*;q=0.3
    [HTTP_COOKIE] => [...]
    [PATH] => /usr/local/bin:/usr/bin:/bin
    [SERVER_SIGNATURE] => 
Apache/2.2.14 (Ubuntu) Server at test.example.com Port 8080


    [SERVER_SOFTWARE] => Apache/2.2.14 (Ubuntu)
    [SERVER_NAME] => test.example.com
    [SERVER_ADDR] => 127.0.0.1
    [SERVER_PORT] => 8080
    [REMOTE_ADDR] => 127.0.0.1
    [DOCUMENT_ROOT] => /var/www
    [SERVER_ADMIN] => webmaster@localhost
    [SCRIPT_FILENAME] => /var/www/index.php
    [REMOTE_PORT] => 54833
    [REDIRECT_URL] => /
    [GATEWAY_INTERFACE] => CGI/1.1
    [SERVER_PROTOCOL] => HTTP/1.0
    [REQUEST_METHOD] => GET
    [QUERY_STRING] => 
    [REQUEST_URI] => /
    [SCRIPT_NAME] => /index.php
    [PATH_INFO] => /
    [PATH_TRANSLATED] => redirect:/index.php/
    [PHP_SELF] => /index.php/
    [PHP_AUTH_USER] => ******
    [PHP_AUTH_PW] => ******
    [REQUEST_TIME] => 1308972068
)

and on a https request it looks like 在https请求上看起来像

Array
(
    [REDIRECT_STATUS] => 200
    [HTTP_HOST] => test.example.com:443
    [HTTP_X_REAL_IP] => 119.224.22.142
    [HTTP_X_FORWARDED_FOR] => 119.224.22.142
    [HTTP_X_URL_SCHEME] => https
    [HTTP_X_FORWARDED_PROTO] => https
    [HTTP_CONNECTION] => close
    [HTTP_USER_AGENT] => Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.100 Safari/534.30
    [HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8
    [HTTP_ACCEPT_ENCODING] => gzip,deflate,sdch
    [HTTP_ACCEPT_LANGUAGE] => en-US,en;q=0.8,en-NZ;q=0.6
    [HTTP_ACCEPT_CHARSET] => ISO-8859-1,utf-8;q=0.7,*;q=0.3
    [HTTP_COOKIE] => [...]
    [PATH] => /usr/local/bin:/usr/bin:/bin
    [SERVER_SIGNATURE] => 
Apache/2.2.14 (Ubuntu) Server at test.example.com Port 8080


    [SERVER_SOFTWARE] => Apache/2.2.14 (Ubuntu)
    [SERVER_NAME] => test.example.com
    [SERVER_ADDR] => 127.0.0.1
    [SERVER_PORT] => 8080
    [REMOTE_ADDR] => 127.0.0.1
    [DOCUMENT_ROOT] => /var/www
    [SERVER_ADMIN] => webmaster@localhost
    [SCRIPT_FILENAME] => /var/www/index.php
    [REMOTE_PORT] => 54841
    [REDIRECT_URL] => /
    [GATEWAY_INTERFACE] => CGI/1.1
    [SERVER_PROTOCOL] => HTTP/1.0
    [REQUEST_METHOD] => GET
    [QUERY_STRING] => 
    [REQUEST_URI] => /
    [SCRIPT_NAME] => /index.php
    [PATH_INFO] => /
    [PATH_TRANSLATED] => redirect:/index.php/
    [PHP_SELF] => /index.php/
    [PHP_AUTH_USER] => ********
    [PHP_AUTH_PW] => ********
    [REQUEST_TIME] => 1308972250
)

and my .htaccess looks like 我的.htaccess看起来像

Options +FollowSymlinks
RewriteEngine on

RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ %1/$1 [R=301,L]


RewriteCond $1 !^(index\.php|robots\.txt|favicon\.ico|css|images|js)
RewriteRule ^(.*)$ index.php/$1 [L] 

So at the very top of my index.php I have 所以在我的index.php的最顶端,我有

$_SERVER['SERVER_PORT'] = explode(':', $_SERVER['HTTP_HOST']);
$_SERVER['HTTP_HOST'] = $_SERVER['SERVER_PORT'][0];
$_SERVER['SERVER_PORT'] = $_SERVER['SERVER_PORT'][1];
if($_SERVER['SERVER_PORT'] == 443)
  $_SERVER['HTTPS'] = 'On';
else
  $_SERVER['HTTPS'] = 'Off';

And on pages where I want HTTPS I call 在我想要HTTPS的网页上,我打电话

function require_ssl(){
    if($_SERVER['HTTPS'] == 'Off') {
        $host = explode(':', $_SERVER['HTTP_HOST']);
        header('location: https://' . $host[0] . $_SERVER['REQUEST_URI']);
        exit;
    }
}

And on pages where I want only HTTP I call 在我只想要HTTP的网页上我打电话

function disable_ssl(){
    if($_SERVER['HTTPS'] == 'On') {
        $host = explode(':', $_SERVER['HTTP_HOST']);
        header('location: http://' . $host[0] . $_SERVER['REQUEST_URI']);
        exit;
    }
}

So, after hours of painful debugging we finally worked out the issue. 因此,经过数小时的痛苦调试后,我们终于解决了这个问题。

Nginx Nginx的
Yep, the load balancer was doing it's own redirects. 是的,负载均衡器正在进行自己的重定向。

In the nginx setup this line existed proxy_redirect http:// https://; nginx设置中,此行存在proxy_redirect http:// https://;

So, what was happening? 那么,发生了什么?

Well, My code was saying "this page should not be https, redirect" 好吧,我的代码说“这个页面不应该是https,重定向”
Then nginx was saying "this request is not https, redirect" 然后nginx说“这个请求不是https,重定向”
Then my code was... 然后我的代码是......
boom redirect loop. 繁荣重定向循环。

So, by changing proxy_redirect http:// https://; 因此,通过更改proxy_redirect http:// https://; to proxy_redirect Off; proxy_redirect Off; we fixed the problem :) 我们修复了问题:)

The function that you posted for disable_ssl() shows: 您为disable_ssl()发布的函数显示:

if($_SERVER['HTTPS'] == '0n') {

Is the 0 ('zero') a copy/paste error? 0 ('零')是复制/粘贴错误吗? I assume that you meant: 我认为你的意思是:

if($_SERVER['HTTPS'] == 'On') {

If I'm following your logic correctly, this function is invoked when you goto https://test.example.com , and so if this typo exists, it is probably not doing what you think it should. 如果我正确地遵循你的逻辑,当你转到https://test.example.com时会调用这个函数,所以如果这个错字存在,它可能没有按照你的想法去做。

We've addressed the accurate fix for Nginx (and other reverse proxies) here: 我们在这里解决了Nginx(和其他反向代理)的准确修复:

http://www.sonassi.com/knowledge-base/magento-kb/magento-https-redirect-loop/ http://www.sonassi.com/knowledge-base/magento-kb/magento-https-redirect-loop/

This avoids the necessity to have that code in your index.php file. 这样就无需在index.php文件中包含该代码。 All you needed to do was add this to your Nginx config, 您需要做的就是将其添加到您的Nginx配置中,

fastcgi_param  HTTPS on;

You might consider using .htaccess rules instead, something like: 您可以考虑使用.htaccess规则,例如:

RewriteCond %{SERVER_PORT} 80 
RewriteCond %{REQUEST_URI} (optional pattern additional url matching)
RewriteRule ^(.*)$ https://test.example.com/$1 [L]

if you want to force http just replace 80 with 443 and https with http. 如果你想强制http只需用443替换80和用http替换https。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM