背景
- 所在部门22年Q4季度开发了个新系统,我负责前端部分的开发,系统中需要开发一个基于
ES
的图形界面,考虑到开发周期和难度,和leader
确认了一下决定使用iframe
嵌入现成的ES kabana
的页面 - 开发测试阶段都没遇到什么大问题,就上测试环境时
kibana
嵌入的页面需要登录认证,用Nginx
代理时给相应请求头里携带kibana
的Authorization
也很快解决了,leader
见测试没问题了,在年后我没回公司的时候(实习生,元旦前阳了请假回家了,年后又请了半个月假)对项目进行了上线,发现页面出不来
问题分析
问题
- 二月中旬回到公司看了一下控制台报错:
Mixed Content: The page at 'https://' was loaded over HTTPS, but requested an insecure frame 'http://'. This request has been blocked; the content must be served over HTTPS.
- 报错很明确
HTTPS
界面引入HTTP
资源,混合资源,浏览器阻止了载入混合内容- 看到这报错瞬间明白了,我待的部门内部的系统就现在开发的这个搞特殊用的
HTTPS
,其他的系统包括该系统的测试环境都是HTTP
- 看到这报错瞬间明白了,我待的部门内部的系统就现在开发的这个搞特殊用的
搜罗的解决方法
- 问题明确了那解决方法也明确了,毕竟有这么经典的一句话“你碰到过的问题总有前人也碰到过搜索引擎会给你答案”,翻阅内部
wiki
加上搜索引擎给的答案总结出了三个方法:
- 将
kibana
的协议升级成HTTPS
- 将开发中的系统生产环境协议降级为
HTTP
- 通过
nginx
代理,代码中更改嵌入页面协议为HTTPS
,通过nginx
代理该链接请求HTTP
的链接
- 从上面的方案来看第一条无疑是最好的,折腾少风险低,还都升级为更安全的
HTTPS
,多好,从网上搜罗的信息发现公司已跳槽的老前辈屈光宇大佬的博客里也推荐使用这种,遂信心满满将方案告知leader
,然后前面两条很干脆的被否决掉了……
障碍
-
leader
给出的解释总结下意思大概如下:kibana
部署的机器是中台的,那儿不好协调,改这个想都别想,第一个方案卒- 现有平台已存在一段时间更改协议有风险,不知道会不会影响到其他系统,就已知引用了该系统的咱自己部门就有一个,第二条方案卒
-
现存方案仅剩走
nginx
代理……
nginx 代理的一些问题
leader
否决掉前两个方案之后就只能走nginx
代理了,也幸亏这方法也不难办,反向代理一下kinaba
的该域名就行,可就是这看似简单的一个代理把我和mentor
给难住了,不管怎么写,代理最后都会走到开发中这个系统的域名上去!- 这个系统原有的
nginx
配置的太“霸道”了,只要是走这个机器的请求,没有域名的统统会被代理到该系统的域名下,kibana
的地址还是裸的协议+ip
+端口,而且这个配置问了mentor
还不敢随意动,不知道哪个犄角旮旯里的代码请求就会走这个…… - 试过了过滤忽略掉
kibana
的地址代理,但是依旧解决不了 - 试过嵌入的页面写开发中系统的域名,代理该链接的
params
也解决不了,嵌入的kibana
页面请求太多了,params前缀还不一样,不可能全给写上,漏掉一个都会跳到现有系统……
- 这个系统原有的
最终方案
- 多次尝试无果之后,无意中发现该系统域名申请的
ssl
证书为
ssl_certificate /search/code/nginx/ssl/_.xxx.xxx.xxx_bundle.crt;
ssl_certificate_key /search/code/nginx/ssl/_.xxx.xxx.xxx.key;
- (
xxx.xxx.xxx
为公司二级域名),也就是说只要申请的三级域名符合以这个二级域名结尾就可以共享这个证书!而询问过后发现再申请一个三级域名就只需要提交个申请就可以,只要符合规则,审核的是自己人! - 申请的域名很快就下来了,该域名也解析到我们项目部署的机器
ip
,有了域名那就好办多了
- 另起一个
nginx
的配置文件- 该配置文件不管他什么请求,只要走这个域名的我们统统给他代理到
kibana
的部署地址上去
- 该配置文件不管他什么请求,只要走这个域名的我们统统给他代理到
server {
listen 443 ssl;
# 申请的域名
server_name kibana.xxx.xxx.xxx;
ssl_certificate /search/code/nginx/ssl/_.xxx.xxx.xxx_bundle.crt;
ssl_certificate_key /search/code/nginx/ssl/_.xxx.xxx.xxx.key;
location ~ .*(.htm|.html|manifest.json)$ {
add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
}
location / {
# kibana 部署地址
proxy_pass http://xxx.xxx.xxx.xxx:xxxx;
# 跳过kibana登录认证
proxy_set_header Authorization "Basic 账号密码生成的base64编码后数据";
}
}
- 将嵌入的
iframe
链接的origin
部分改为我们现在刚申请的这个域名
问题解决
后记
虽然是个很小的问题,但是解决的过程却十分艰难,本来只要大家配合几下子就解决的问题却卡了我三天,最终还是通过曲线救国的方式解决掉的,后期项目开发换人了维护的成本也远比直接将kibana
协议升级来的高,职场有时候真不是理论上的最佳方案就是最佳,结合实际的各方阻碍,最终的解决可能在我们最初看来真的不那么完美。