测试平台系列(143) 解决代理的难题.md

2022/6/23 测试平台接口测试FastApiPythonReact

大家好~我是米洛
我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的教程,希望大家多多支持。
欢迎关注我的公众号米洛的测开日记,获取最新文章教程!

# 回顾

上一节我们已经能够打通【har文件实现录制=>用例生成】的整体流程。那么这一节我们就继续把录制相关的逻辑理清楚。

还记得我们之前抛出的问题不?

我这里其实陆陆续续发现过好几个坑,但是都一一踏平了,今天这节就无私奉献出来,希望有缘人能少踩弯路。

# 本地不易察觉的问题

为什么问题拖了那么久,那是因为这些问题本地都不容易发觉,只有到了线上才会出现。举个例子,我们本地启动的mitmproxy的服务地址是: 127.0.0.1:77778

我们的请求经过了代理之后,也还是127.0.0.1,也就是说ip并没有变化,所以这会导致我们发现不了问题!!!

今天我要说的问题主要分2类:

  • 第三方云服务器商

    之前我们截过图,腾讯云会拦截我们的mitm.it页面,提示我们没有备案,这就导致什么?

    对,我们无法通过mitm.it安装证书。

  • ip问题

    还记得我们是怎么判定一个用户有没有在录制,录制得怎么样的吗?没错,我们是根据ip来的,想一下服务上线后,我们的ip依然是127.0.0.1, 线上我们可能经过了nginx,也可能经过了其他各类服务器转发, 那我们的真实ip,他们还能完美拿到吗?

    答案是不一定的。

# 逐个击破

  • 云服务器商

    对付他们,其实没有太多办法。但我们本地配置代理以后,访问到mitm.it (opens new window),可以观察到,对应的证书,我们是可以下载到的,而且不同操作系统的证书是固定的。

也就是说我们在自己的Request客户端里面加上自身代理(云服务器给自己代理),也就是类似requests.get下载mitm.it的文件,但因为要代理才能访问,所以我们需要给requests加入proxy相关的参数。

这个我已经封装好了,因为之前计算走mock模式。

云服务器(通过本机代理)访问mitm.it行得通,所以我们可以对外暴露一个api:下载证书

这个证书只要下载到,我们就能顺利安装并通过代理访问到其他页面,为后面录制做铺垫了。

  • ip问题

    这个是困扰我很久的一个问题,先来看第一个。先假设我们的真实ip都是111.111.111.111,所以我们对照录制状态这个接口:

这一块的内容,我们希望的是根据我们的真实ip去获取redis里面的数据,但最终走向会是什么呢?

  1. 前端页面发起请求
  2. 请求到达服务端nginx
  3. nginx转发到pity真实地址

也就是说,pity收到的请求,其实是由nginx发给它的,那他拿到的,其实是nginx的ip地址,即nginx服务器地址

这就引发第一个问题,我们获取不到我们的录制数据(注意本地并不会出现哦,只有生产会)。

那么怎么解决呢?我们的nginx在转发的时候,要带上对应的配置:

* 注意这个client_max_body_size,默认是1m,这里是har导入的时候报错我修改的。

这3个配置代表,把原始的客户端ip啥的也都继续转发过去。如此我们就解决了第一个问题。

  • 第二个问题

    第二个问题比较粗鲁,由于我们录制的时候,我们实际上是走了mitmproxy的代理,但是他也很坏,不给我们真实ip,只要我们经过他,通过fastapi获取到的,都是mitmproxy部署的地址。

    经过我不断的探索,终于找到了对应的解决方案,直接上答案。

  1. 修改uvicorn的配置

我是用gunicorn的方式,所以我在gunicorn.py里面修改uvicorn的配置:

# 启动的进程数
workers = multiprocessing.cpu_count()
worker_class = 'uvicorn.workers.UvicornWorker'
forwarded_allow_ips = "*" 
x_forwarded_for_header = 'X-FORWARDED-FOR'
1
2
3
4
5

forwarded_allow_ips这个参数是允许forward的ip,我理解的意思是,你重定向/转发以后,继续输送你旧的ip。

其实nginx的配置,也是这个参数,对不,其实大家命名都很接近,网络上有些人会要求再改一个header啥的配置,我观察了一下那个配置默认是的,所以不需要了。

改完这个之后,你的mitmproxy就会收到你真实地址,但是这样是不够的。我们如果录制数据,会走代理,这样我们的ip会被识别为mitmproxy所在ip。

所以我们需要继续提升(forward),我们需要在mitmproxy录制到接口的时候也设置forward

在插件中,把真实的ip地址forward即可。下面来展示,我在pity.fun这个地址里面录制回放的成果。

# 劳动成果

  1. 配置代理

  1. 全程使用pity.fun环境录制

#

bug警钟,可以看到最后录制结果多了一条开始录制的数据,我们下期解决它。