背景
公司安全要求对外开放的站点必须为Cookies设置Secure属性,而
标记为 Secure 的 Cookie 只应通过被 HTTPS 协议加密过的请求发送给服务端,因此可以预防 man-in-the-middle 攻击者的攻击。
同时,业务的https请求路径如下:
User-Agent —[https]—> haproxy(公司级接入) —[http]—> nginx(业务级接入) —[http]—> nodejs(后端服务接入)
解决方案
egg config.proxy属性
根据Issues,修改项目配置
config.proxy = true;
config.cookies = {
secure: true
};
本地nginx测试通过。发上测试服后,发现所有请求返回500错误
Cannot send secure cookie over unencrypted connection
查看egg-cookie的实现,发现ctx.secure 仍然是 false, 服务拿到的protocol仍然是http. 查看业务的nginx配置,发现关于转发的部分如下:
location ^~ /api/ {
proxy_set_header X-Forwarded-Proto $scheme;
}
而查看nginx日志发现,业务拿到的scheme是http, 导致服务最后拿到的也是http。 发现测试服比本地多了一层nginx代理, 修改配置
location ^~ /api/ {
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
}
后一切正常
注意事项
之所以需要这么改是因为实际的网络路径会存在多层代理,比如我们的https层其实只建立在用户到公司网关上。在最外层的nginx上已经设置
proxy_set_header X-Forwarded-Proto $scheme;
而nginx每一层获取到的scheme是指到这一层到底是用的http还是https协议。