wudision0416

PHP-FPM + Nginx 架构下解决SSL不输出 $_SERVER['HTTPS'] 问题
最近在搭建Discuz X,因为考虑支持HTTPS,所以按照经验来部署证书,系统环境选择的是LNMP,用的Onei...
扫描右侧二维码阅读全文
04
2018/06

PHP-FPM + Nginx 架构下解决SSL不输出 $_SERVER['HTTPS'] 问题

实践日期:2018/05/26;服务器:阿里云Ubuntu 16.04;软件版本:PHP 5.6/Nginx1.12

最近在搭建Discuz X,因为考虑支持HTTPS,所以按照经验来部署证书,系统环境选择的是LNMP,用的Oneinstack一键部署。但是chrome一直都提示不安全:此网页正试图从未经验证的来源加载脚本 。这说明我页面上加载的资源不纯粹是https的,有部分是http的或者有些资源不支持https却用了https。打开浏览器控制台找到提示的源,发现基本都是功能组件加载的时候是以http加载的。
在搜索学习之后,才定位到问题所在,例如在source/class/discuz/discuz_application.php文件中

$_G['isHTTPS'] = ($_SERVER['HTTPS'] && strtolower($_SERVER['HTTPS']) != 'off') ? true : false;

使用$_SERVER['HTTPS']来判断是http还是https,但在Nginx+PHP-FPM架构下,nginx使用fastcgi_pass指令将请求传递给PHP-FPM,但是在使用fastcgi_pass时,Nginx默认不会将HTTPS传递给PHP-FPM。如果你使用的是Apache,它就会自动设置HTTPS服务器变量,PHP代码可以通过 $ _SERVER ['HTTPS']检查以确定请求是HTTPS还是HTTP。那现在就需要需改nginx配置或者discuz程序来解决问题。基于服务器的兼容性考虑,还是修改nginx配置。因为很多CMS程序(WordPress,Drupal,...)都是使用 $ _SERVER ['HTTPS']来确定请求是HTTPS还是HTTP。修改方法如下:

方法1:增加 一个fastcgi_param 环境变量即可。

fastcgi_param  HTTPS 'on';

将上述代码添加至网站对应的Nginx配置文件中。但要注意,按我理解,这样也会导致一个问题。因为这种方式属于写死了环境变量,因此要注意作用域的问题,在此环境变量生效的区域,程序一律认为是https请求。如果你的站点两种请求都支持,建议把两种请求的配置分开写,类似与人工预设请求的类型。我的网站决定已经只支持https,所以这种方式问题不大,http的请求也设置了跳转至https。所以我只需要是写在虚拟机配置文件中即可。

方法2:修改web程序的判断方式,不要只根据环境变量来判断,增加一个请求的端口的判断条件。我们一般HTTP请求都使用80端口,而HTTPS则使用443端口。按照这个思路,可以将上诉文件中的代码改为如下所示。

$_G['isHTTPS'] = ($_SERVER['SERVER_PORT'] == 443 || $_SERVER['HTTPS'] && strtolower($_SERVER['HTTPS']) != 'off') ? true : false;

Discuz并非修改此处即完成所有工作,详情请搜索详细处理办法。

方法3:你要把代理程序改成Apache我也是没办法啊。

后记:记得检查其他引用资料是否为https 比如模板中备案号查询地址等处。有问题欢迎留言讨论!

最后修改:2018 年 06 月 04 日 11 : 06 PM
如果觉得我的文章对你有用,请随意赞赏

2 条评论

  1. Sligcm

    感谢分享。

  2. wudision0416

    自己的沙发自己占

发表评论