当我尝试从SSL加密页面切换回非加密(https - > http)时,我遇到了陷入无限重定向循环的情况。我们当前的配置设置在负载均衡器后面,该负载均衡器创建一个标头:HTTP_X_FORWARDED_PROTO
当它设置为SSL时,它返回“https”,oth,它总是返回“http”
我将以前在SSL证书上使用的代码移到负载均衡器而不是运行该站点的Web节点。已添加(HTTP_X_FORWARDED_PROTO)以相应地更新脚本。
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])){
$redirect = '';
if (!isset($sslPage)){
$sslPage = false;
}
switch($_SERVER['HTTP_X_FORWARDED_PROTO']){
case 'http' :
if ($sslPage)
$redirect = 'location: https://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
break;
case 'https' :
if (!$sslPage)
//$redirect = 'location: http://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
break;
}
if (!empty($redirect)){
header ($redirect);
}
}
每个需要打开ssl的页面都有一个$ sslPage = true的预加载变量;
因此从http到https的重定向效果很好..没问题。但如果我试图倒退它就行不通。我陷入无休止的循环中。我开始认为这是因为apache。由于Web节点不再终止SSL,所有流量都通过端口80运行。当php通过header()进行重定向时,我相信服务器会收集请求,因为它是本地的并尝试解析它。由于HTTP_X_FORWARDED_PROTO从未更新,因为它没有再次点击负载均衡器,因此重定向永远不会成功。
我的问题是,如果这是有道理的,或者我对此有何看法?这个电话会不会总是被转发回负载均衡器?如果它确实保留在该Web节点的内部,我该如何强制它返回Load Balancer,以便它可以为它试图检索的页面编写新的标题?
事实证明这令人沮丧......
提前感谢您的帮助。
答案 0 :(得分:6)
您可以通过设置环境变量(在PHP逻辑$_SERVER['HTTPS']
中)让Apache 认为 启用SSL。
SetEnvIf X-Forwarded-Proto https HTTPS=On
这应该允许遗留代码在不需要更改的情况下工作。
答案 1 :(得分:2)
我们刚遇到类似的事情,发现我们的Zeus负载均衡器干扰了响应头。 我们发现,如果初始请求是在https上进行的,并且返回到非安全页面,那么发送回的任何301/302标头都会被负载均衡器修改。
例如,如果客户请求https://site.com并且我们使用302重定向到http://site.com,则返回客户端的结果将为“位置:https://site.com “因为负载均衡器已将其切换回来(而不是预期的”位置:http://site.com “)
通过在负载均衡器中关闭此功能解决了这个问题。
希望能帮助某人 - 尝试并深入了解这是一个令人讨厌的问题!