背景
由于公司的所有研发效能的数据都在云效平台 (公司内部平台),某天我们想通过脚本拉取一下用户反馈数据,首先要通过 chrome 调试工具定位到了具体那个是网络请求.
一个很简单的 get 请求,curl 命令如下文章源自玩技e族-https://www.playezu.com/179777.html
curl 'https://one.xxxx.xxxx.com/api/v4/feeback/?entityId=990123&entityType=3' -H '1: 1' -H 'Connection: keep-alive' -H 'Pragma: no-cache' -H 'Cache-Control: no-cache' -H 'sec-ch-ua: "Chromium";v="94", "Google Chrome";v="94", ";Not A Brand";v="99"' -H 'Authorization: Bearer xxxxxx' -H 'sec-ch-ua-mobile: ?0' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36' -H 'sec-ch-ua-platform: "macOS"' -H 'Accept: */*' -H 'Sec-Fetch-Site: same-origin' -H 'Sec-Fetch-Mode: cors' -H 'Sec-Fetch-Dest: empty' -H 'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8' --compressed
简单分析在 header 中有个参数是"Authorization","Authorization"是一版内部系统通过 JWT 或者加密算法生成的认证.文章源自玩技e族-https://www.playezu.com/179777.html
尝试过这个"Authorization"的有效期一般是七天,一般会在生成的时候给出有效时间.文章源自玩技e族-https://www.playezu.com/179777.html
常用的两种方式.文章源自玩技e族-https://www.playezu.com/179777.html
1、平台提供的对外接口能力文章源自玩技e族-https://www.playezu.com/179777.html
这个接口目前没有提供对外接口,需要开发并且优先级不高 (走不通).文章源自玩技e族-https://www.playezu.com/179777.html
2、平台提供永不过期的"Authorization"文章源自玩技e族-https://www.playezu.com/179777.html
平台暂时不提供类似后门参数 (走不通).文章源自玩技e族-https://www.playezu.com/179777.html
调研
初步调研
因为上面两种方式都不能解决,所以自动化脚本只能抓包固定写死"Authorization",但是手工维护的成本高.文章源自玩技e族-https://www.playezu.com/179777.html
所以还是想通过技术方式解决,换了一个思路去解决.核心是怎么自动的拿到"Authorization",并且可以自动续上"Authorization"的有效期.文章源自玩技e族-https://www.playezu.com/179777.html
那么新的方案来了,拆解一下需求分为两步.
1、怎么自动的拿到"Authorization"
2、以自动续上"Authorization"的有效期.
解决问题一:
1)、因为平时每天都会自动在云效平台 (公司内部平台),那么如果我能自动化拦截"浏览器"发出的请求并且拿到请求头参数就可以了.
2)、可以通过代理工具自动化拦截,比如 anyproxy 写个脚本就可以.
但是需要浏览器绑定代理工具,太麻烦不可取.
3)、chrome 插件有没有可能做到自动化拦截请求,我把这个想法告诉专业的前端同学,提供了我一个工具的思路
modheader 这个工具主要用途是方便修改请求头信息.
工程地址
https://github.com/bewisse/modheader
既然工具能修改请求参数的话,必定能拦击请求.我大概猜的是 hook 了网络请求的所有流程.
研究源码
我把代码 clone 下来开始研究源码,到底是什么修改了 header.
代码是纯 js 写的,毕竟是加载到浏览器中.
一个 chrome 插件会包含哪些文件及文件夹
│ manifest.json │ ├─html │ index.html │ ├─images │ icon-128.png │ icon-16.png │ ├─scripts │ background.js │ ├─styles │ main.css │ └─_locales ├─en │ messages.json │ └─zh_CN messages.json
简单说明一下:
- html:存放 html 页面
- images:存放插件图标
- scripts:存放 js 文件
- styles: 存放样式
- _locales: 存放多语言文件
- manifest.json:一些关于插件的元数据,作为 chrome 入口文件
UI 层代码是".svelte"类型的文件
Svelte 是一种全新的构建用户界面的方法。传统框架如 React 和 Vue 在浏览器中需要做大量的工作,而 Svelte 将这些工作放到构建应用程序的编译阶段来处理
https://www.sveltejs.cn/
随便看了一个.svelte 文件,还是能看懂是有 html 和 js 代码.
搜索"Request headers"关键字能定位到修改 header 的地方
"setupHeaderModListener"是初始化 header 的监听.
"modifyRequestHeaderHandler_"是每次修改 heaer 的方法.
看到这里感觉已经差不多找到自己想要的了.
"modifyHeader"才是真正的修复 header 的方法,如下是修改的代码.
debug
在 debug 调试的时候,用打印日志是看不到的.所以用 alert 方式可以调试展示参数.
Chrome 插件应该有本地调试的方式,不过我还没有用到.
打包
在 package.json 找到对应打包命令
npm run build-all
安装
选择 chrome 文件夹
chrome 浏览器输入
chrome://extensions/
点击加载已解压扩展程序
加载编译好的插件
选择插件
随便输入并且回车即可
上面的流程就可以通过 chrome 插件拿到"Authorization"
如何做到永不过期的"Authorization"
这里需要一个后端服务,每次把"Authorization"参数发给后端.
服务端逻辑:
1、判断数据库是否有 Authorization,如果没有直接插入.
2、如果有的话,判断 Authorization 是否有效, 如果有效继续使用. 如果失效,更新 Authorization 的参数.
使用发送网络请求验证返回结果,判断 Authorization 是否有效
这种方式对服务端有一定性能问题,后续考虑发请求放到消息队列中处理.
心得
1、能通过技术方式解决,一定要通过技术方式解决.
2、学习新技术都是通过痛点探究的另一个未知的领域.
3、形成文档多总结.
参考
一天学会 Chrome 插件开发
https://zhuanlan.zhihu.com/p/28889449
未知地区 1F
学习了。牛逼,已收藏http://xinxi.work/ ,点开 502信老师牛逼,哈哈这类小场景工作中也确实出现过几次,楼主很不错竟然去实践了一回(我们都是临时脚本,手动贴一下 cookie 本地跑完就了事了)。
我自己的想法是,用无头浏览器如 Headless Chrome 来登录网站,使用 selenium 去发送任意请求获取请求 headers 中的 Authorization,再利用任意数据库做个 Authorization 的缓存来判断 Authorization 是否需要更新,最终实现楼主一样获取 “永不过期” 的 Authorization。
不过上面的想法有个前提需要解决,就是在无头浏览器中怎么登录……如果是简单的账户密码登录那还好,大家各自使用写个配置文件就行(但是安全性不高易泄露);如果是复杂的验证码登录,甚至是手机扫码登录,就开始难搞了……
所以还是楼主的方案更有实用性。再试下用 fiddler 插件去实现也是一个不错的选择 既然是公司内部的系统,拿到 auth 的算法生成一下就可以了吧大神还是大神通过实现一个目标,涉及了很多知识呀!学习到了!