修复:lnmpa下启用SSL后Magento Redirection loop的问题

Web服务器环境: linux + Ningx proxy + Apache + mod_php + MySQL
由Nginx 提供静态文件处理,PHP文件通过代理的方式由 Apache mod_php 来处理PHP请求。

网站用Mangeto程序,在未启用SSL HTTPS的情况下提交了Google shopping Feed, 在Google Merchant center 后台显示数据质量没有任何问题,但是查看已发布的商品 后发现没有任何数据。于是查看官方文档:付款方式类型符合在线购买方式 中提到 “付款和交易过程必须是安全的(经 SSL 加密)”。

于是迅速购买了个RapidSSL CA 安装在装了LNMPA环境服务器上,问题来了,https协议下打开网站,提示:This web page has a redirect loop.(如图)

Magento https redirect loop

Magento https redirect loop

Google了一两天找了很多资料,其中在芳草苑的这篇文章里找到了有价值的线索 SSL, Nginx and Magento : 原因是Nginx的默认配置中,没有给PHP程序传递通信协议,于是 $_SERVER[] 系统常量里缺少 HTTPS directive,在lnmp 的php-fpm的配置环境下添加:

fastcgi_param HTTPS on;
server {
    listen 443;
    ... more config here, include SSL ...
    location ~ \.php$ {
        ... FastCGI config here ...
        fastcgi_param HTTPS on;
    }
}

这个问题就能解决。

但是在代理模式下,问题依旧,后来又在Naruzo’s blog的文章 SSL with Magento behind a load balancer 中找到重要启发。
在代理环境下添加以下配置
重要步骤1:

proxy_set_header   X-Forwarded-Proto $scheme;

给PHP的$_SERVER 变量数组显式增加发起请求的脚本协议。
添加改配置文件保存后运行:service nginx -s reload 重新加载配置文件。
然后用如下一句话脚本测试看看通信协议是否已经添加:

file: s.php
<?php
print_r($_SERVER);
?>

运行https://example.com/s.php
查看源代码,如果看到这句 [HTTP_X_FORWARDED_PROTO] => https 表示第一步已经成功。
完整的proxy.conf 配置内容如下:

proxy_connect_timeout 30s;
proxy_send_timeout   90;
proxy_read_timeout   90;
proxy_buffer_size    32k;
proxy_buffers     4 32k;
proxy_busy_buffers_size 64k;
proxy_redirect     off;
proxy_hide_header  Vary;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
proxy_set_header   Accept-Encoding '';
proxy_set_header   Host   $host;
proxy_set_header   Referer $http_referer;
proxy_set_header   Cookie $http_cookie;
proxy_set_header   X-Real-IP  $remote_addr;
proxy_set_header   X-Forwarded-By    $server_addr:$server_port;
proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header   X-Forwarded-Proto $scheme;

引用proxy.conf 的相关配置文件如下:

                location @apache {
                        internal;
                        proxy_pass http://127.0.0.1:88;
                        include proxy.conf;
                        }

                location ~ .*\.(php|php5)?$
                        {
                                proxy_pass http://127.0.0.1:88;
                                include proxy.conf;
                        }

并在Magento 根目录的index.php里,Mage::run($mageRunCode, $mageRunType); 代码前添加如下代码,
重要步骤2:

if( isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
    $_SERVER['HTTPS'] = 'on';
    $_SERVER['SERVER_PORT'] = 443;
}

经过以上两步,redirect loop 问题完美解决,网站用https 协议打开正常了。

PS:网上提到的此类信息很少,记录一下,方便遇到此类问题的后来者。
BTW: 由于很少动手写文章,有点罗嗦,请各位看官见谅。