使用SSL在PHP负载均衡器后面重定向循环

时间:2012-03-22 00:08:20

标签: php apache redirect header

当我尝试从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,以便它可以为它试图检索的页面编写新的标题?

事实证明这令人沮丧......

提前感谢您的帮助。

2 个答案:

答案 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 “)

通过在负载均衡器中关闭此功能解决了这个问题。

希望能帮助某人 - 尝试并深入了解这是一个令人讨厌的问题!