前言
AnyProxy不僅僅可以抓包,還可以攔截請求並修改服務端響應,實現接口mock功能。
面試時候經常會問到第三方支付如何測試這種,如果對接的第三方沒提供測試環境,那么就需要搭建一個mock服務器,模擬支付接口返回的各種情況。
rule模塊
AnyProxy提供了二次開發的能力,你可以用js編寫自己的規則模塊(rule),來自定義網絡請求的處理邏輯。
注意:引用規則前,請務必確保文件來源可靠,以免發生安全問題
- 攔截並修改正在發送的請求
可修改內容包括請求頭(request header),請求體(request body),甚至是請求的目標地址等
- 攔截並修改服務端響應
可修改的內容包括http狀態碼(status code)、響應頭(response header)、響應內容等
- 攔截https請求,對內容做修改
本質是中間人攻擊(man-in-the-middle attack),需要客戶端提前信任AnyProxy生成的CA
開發示例
舉個栗子: 需要編寫一個規則模塊,在 GET http://httpbin.org/user-agent 的返回值里加上測試信息,並延遲5秒返回
Step 1,編寫規則如下, 保存為sample.js文件,可以放電腦任意位置
// file: sample.js module.exports = { summary: 'a rule to hack response', *beforeSendResponse(requestDetail, responseDetail) { if (requestDetail.url === 'http://httpbin.org/user-agent') { const newResponse = responseDetail.response; newResponse.body += '- AnyProxy Hacked!'; return new Promise((resolve, reject) => { setTimeout(() => { // delay resolve({ response: newResponse }); }, 5000); }); } }, };
Step 2, 啟動AnyProxy,加載規則
anyproxy -i --rule sample.js
當看到出現:Active rule is: a rule to hack response 那就是加載成功了
Step 3, 測試規則
用curl測試
curl http://httpbin.org/user-agent --proxy http://127.0.0.1:8001
也可以使用瀏覽器測試,配置瀏覽器http代理為 127.0.0.1:8001,訪問 http://httpbin.org/user-agent, 經過代理服務器后,期望的返回如下
{
"user-agent": "curl/7.43.0" } - AnyProxy Hacked!
Step 4, 查看請求信息.瀏覽器訪問http://127.0.0.1:8002 ,界面上能看到剛才的請求信息
處理流程
當http請求經過代理服務器時,具體處理過程是:
-收集請求所有請求參數,包括method, header, body等
- AnyProxy調用規則模塊beforeSendRequest方法,由模塊做處理,返回新的請求參數,或返回響應內容
- 如果beforeSendRequest返回了響應內容,則立即把此響應返回到客戶端(而不再發送到真正的服務端),流程結束。
- 根據請求參數,向服務端發出請求,接收服務端響應。
- 調用規則模塊beforeSendResponse方法,由模塊對響應內容進行處理
- 把響應信息返回給客戶端
當代理服務器收到https請求時,AnyProxy可以替換證書,對請求做明文解析。
- 調用規則模塊beforeDealHttpsRequest方法,如果返回true,會明文解析這個請求,其他請求不處理
- 被明文解析后的https請求,處理流程同http一致。未明文解析請求不會再進入規則模塊做處理。
如何引用
如下幾種方案都可以用來引用規則模塊:
使用本地路徑
anyproxy --rule ./rule.js
使用在線地址
anyproxy --rule https://sample.com/rule.js
使用npm包,AnyProxy使用require()加載本地規則,你可以在參數里傳入一個本地的npm包路徑,或是某個全局安裝的npm包
anyproxy --rule ./myRulePkg/ #本地包 npm i -g myRulePkg && anyproxy --rule myRulePkg #全局包
rule接口文檔
規則模塊應該符合cmd規范,一個典型的規則模塊代碼結構如下。模塊中所有方法都是可選的,只需實現業務感興趣的部分即可。
module.exports = { // 模塊介紹 summary: 'my customized rule for AnyProxy', // 發送請求前攔截處理 *beforeSendRequest(requestDetail) { /* ... */ }, // 發送響應前處理 *beforeSendResponse(requestDetail, responseDetail) { /* ... */ }, // 是否處理https請求 *beforeDealHttpsRequest(requestDetail) { /* ... */ }, // 請求出錯的事件 *onError(requestDetail, error) { /* ... */ }, // https連接服務器出錯 *onConnectError(requestDetail, error) { /* ... */ } };
更多資料參考anyproxy 官方文檔https://github.com/alibaba/anyproxy/blob/master/docs/cn/src_doc.md