HTTPS跨越问题处理方法


HTTPSHTTP 的基础上增加了 SSL/TLS 加密,提供了更加安全的传输协议,俨然已经属于各大网站的标配。HTTPS 在原有 HTTP 握手的基础上,增加了证书的验证,进行了加密,解决的问题包括运营商劫持、中间人攻击、钓鱼网站、提升 SEO 等。

HTTPS跨越问题处理方法


1. 同源策略之使用不同的协议

问题起因:两个服务使用的同一域名但不同协议

  • 因为公司有一个产品需要在网站内部引入外部文档,提供的是 HTTP 的地址。我们测试环境使用的也是 HTTP 的网址,所以测试不存在问题,可以正常显示外部文档内容。但是更新到正式环境之后,发现原本能够访问的文档不能访问。后来发现我们正式环境使用的是 HTTPS 的域名,因为浏览器同源策略的问题导致无法访问。

HTTPS跨越问题处理方法 - 浏览器同源策略


问题经过:配置 Nginx 服务间接使用

  • 因为浏览器同源策略的问题,导致在 HTTPS 的网站中无法引用 HTTP 网站的资源。所以,只能配置 Nginx 使访问的时候,间接的通过代理的方式来访问对应的资源。
server {
    listen 443 default ssl;
    server_nam xxx.xxx.com;

    ssl_certificate            "/etc/ssl/certs/xxx.crt";
    ssl_trusted_certificate    "/etc/ssl/certs/xxx.crt";
    ssl_certificate_key        "/etc/ssl/private/xxx.key";

    ......

    location /xxx/xxx/ {
        proxy_pass_header Server;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_set_header Referer "http://www.xxx.xxx";
        proxy_http_version 1.1;
        proxy_pass http://www.xxx.xxx;
    }
}
  • 但是配置之后发现还是无法正常显示引用的外部文档,通过浏览器自带的控制台,发现基本和之前的情况是一样的,还是显示是因为同源策略导致的。后来,通过 curl 测试发现,在访问的时候,经过了一次 302 跳转。很奇怪,为什么还需要跳转呢?

  • 通过浏览器自带的控制台,再次对请求进行分析,发现 proxy_pass 代理的 http://www.xxx.xxx 网站 302 到了 http://www3.xxx.xxx 上面,这时候才真正的得到了 200 的文件内容。所以,对 Nginx 配置进行了调整。将 proxy_pass 的地址改到了真正的服务域名上面,即可。

location /xxx/xxx/ {
    proxy_pass_header Server;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Scheme $scheme;
    proxy_set_header Referer "http://www.xxx.xxx";
    proxy_http_version 1.1;
    proxy_pass http://www3.xxx.xxx;
}
  • 重载配置文件,访问内容,正常了。后来发现是数据库中存储的就是一个假地址,很是尴尬。

问题起因:两个服务使用的不同域名且不同协议

  • 需要部署了两个系统,A 系统和 B 系统,其中 B 系统需要通过 iframe 的方式嵌入到 A 系统中,通过配置单点登录的方式,使用户通过 A 系统来使用 B 系统的服务。但是,等到服务配置完成之后,点击跳转的时候提示 401 错误。排除了,Token 过期和用户没有登录的可能,那就一定是权限哪里配置存在了问题。

问题经过:配置 Nginx 服务间接使用

  • 排查问题时发现,在 iframe 中确实是正确配置了相关单点登录的跳转地址,且本地直接访问地址是可以通过测试的,但是通过 Network 发现,紧接着有 302 跳转了一次,随即提示 401 权限错误。

HTTPS跨越问题处理方法 - 浏览器同源策略

  • 发现要是 iframe 的地址和父级的地址不同源,项目登录时无法设置 cookie,则就是因为这个原因导致请求在 302 跳转之后出现了权限问题(没有把设置的 cookie 信息带过去)。
  • Chrome51 开始,浏览器的 cookie 新增加了一个 SameSite 属性,用来防止 CSRF 攻击和用户追踪。该设置当前默认是关闭的,但在 Chrome80 之后,该功能默认已开启。所以当你无法使用某些网站第三方登录功能的时候,请查看一下是否受到了该设置的影响。
# 接口设置cookie时提示
this set-cookie didnot specify a "sameSite" attribute and was defaulted to "sameSite=Lax" and broke
the same rules specified in the SameSiteLax value
  • 解决方法一 打开 Chrome 设置禁用对应配置项,然后重启浏览器。

HTTPS跨越问题处理方法 - 浏览器同源策略

  • 解决方法二 通过在 Nginx 中代理相关请求到 B 系统上,来间接使用并避免同源策略导致的登录异常问题。
location /xxx/xxx/ {
    proxy_http_version 1.1;
    proxy_pass_header Server;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Scheme $scheme;
    proxy_pass http://www.xxx.xxx;

3. 关于同源策略的相关科普

参考链接地址:点击即可

[1] 什么是同源策略?

  • 同源策略 SOP(Same origin policy) 是一种约定,由 Netscape 公司 1995 年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到 XSSCSFR等攻击。所谓同源是指 “协议+域名+端口” 三者相同,即便两个不同的域名指向同一个 IP 地址,也非同源。
URL                                      说明                    是否允许通信
http://www.domain.com/a.js
http://www.domain.com/b.js         同一域名,不同文件或路径           允许
http://www.domain.com/lab/c.js

http://www.domain.com:8000/a.js
http://www.domain.com/b.js         同一域名,不同端口                不允许

http://www.domain.com/a.js
https://www.domain.com/b.js        同一域名,不同协议                不允许

http://www.domain.com/a.js
http://192.168.4.12/b.js           域名和域名对应相同ip              不允许

http://www.domain.com/a.js
http://x.domain.com/b.js           主域相同,子域不同                不允许
http://domain.com/c.js

http://www.domain1.com/a.js
http://www.domain2.com/b.js        不同域名                         不允许

[2] 同源策略限制那些行为?

  1. CookieLocalStorageIndexDB 无法读取
  2. DOMJS对象无法获得
  3. AJAX 请求不能发送

[3] 跨域解决方案

  1. 通过jsonp跨域
  2. document.domain + iframe跨域
  3. location.hash + iframe
  4. window.name + iframe跨域
  5. postMessage跨域
  6. 跨域资源共享(CORS)
  7. Nginx代理跨域
  8. NodeJS中间件代理跨域
  9. WebSocket协议跨域

4. 最后陈述总结

比如你有 API 等对外服务,早期开放了 HTTP 调用的接口。那么很遗憾,当我们升级到 HTTPS 的时候,能做的事情是通过公告、邮件等方式告知第三方,我们在特定时间后就不在支持 HTTP 服务,希望第三方支持 HTTPS 调用。或者如果安全性不重要的话,那么就同时支持 HTTP/HTTPS 调用。苹果 HTTPS 的公告 App Transport Security 就是很好的例子,而实际上 App 内部还是留了开启 HTTP 请求的设置。


5. 参考链接记录

送人玫瑰,手有余香!


文章作者: Escape
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Escape !
  目录