• 移动端如何实现网络请求抓包功能?
  • 发布于 1周前
  • 50 热度
    0 评论
开发环境
MacBook Pro(13-inch, M1, 2020)、Fultter SDK 3.7.6、Proxyman 4.4.0、vsCode

什么是抓包
抓包就是将网络传输发送与接收的数据包进行截获、重发、编辑等操作,在网络安全、移动端项目开发、爬虫中应用较为广泛。在浏览器中,可以通过控制台的 Network 面板来对网页发出去的请求进行分析与断点调试,通过抓包不仅可以对浏览器发出去的请求进行拦截,还可以对经过代理服务器(抓包工具)的请求进行拦截。因此在移动端项目前后端联调中,可以利用抓包将请求的 Curl 发给后端便于后端进行接口处理逻辑的定位。

抓包的基础实现
抓包的实现原理主要涉及监听网络接口、截获数据包、存储数据包、解析数据包和分析数据包等步骤,使用户能够监视和分析网络通信中传输的数据包。

在网络请求中,HTTP 和 HTTPS 是最为常见的客户端和服务端数据交换的连接方式,抓包工具对 HTTP 的拦截是轻而易举的,在 HTTP 中数据的传输是明文传输,除了客户端对明文进行加密外,抓包工具抓到的数据就是明文的。HTTPS 是在 HTTP 的基础上使用 TLS/SSL 加密,如果想在抓包工具上对加密的数据进行解密后分析,就需要让客户端信任抓包工具就是目标服务器,因此作为服务器的一方就需要对发出请求的客户端颁发证书,让客户端信任抓包工具就是目标服务器,否则通常在客户端会出现抓包数据拦截失败或者请求发不出去的问题。

HTTPS 之所以安全是因为在建立客户端和服务端加密通信的证书是由权威的 CA 机构签发的,受信任的 CA 机构的根证书会在设备(电脑、手机等通信设备)出厂前预装在操作系统中,用来验证服务器发来的证书是否由 CA 签发。那么为了解决这样的一个问题,抓包工具就会将自己的根证书导入到系统中,这样一来就能完成建立加密通信时对中间人证书的验证。

工具安利
我用过两款抓包工具,分别是 Fiddler 和 Proxyman,在使用的过程中两者并无差异,但是 Proxyman 相对于 Fiddler 而言,个人觉得 Proxyman 界面更加优雅美观,在使用上,Proxyman 也易上手。目前,我正在用 Proxyman 这款工具,就我个人而言,我用来抓取移动端发出去的请求,将报错的接口复制出 Curl 后发给后端开发的同学。

Proxyman & 开发调试
背景
最近在 vsCode 上用 Flutter 开发移动端项目,在前后端联调时,需要将报错的 Curl 拷贝下来发给后端供后端开发同学去定位和排查问题。在开发的过程中,Flutter SDK 提供相关的网络调试功能,但是缺点在于不管是在 vsCode 或者是在浏览器中打开,当我想复制 Curl 的时候会发现复制不了,为了解决这个问题和凭借过往在 Win 上使用 Fiddler 来调试网络请求的经验,我在 macOS 上也利用了第三方抓包工具(Proxyman)来进行调试。

Proxyman 证书
首先,先在 macOS 上安装 Proxyman 根证书,具体原因参考前文 “抓包的基础实现”,这样 Proxyman 也能够充当 PC 的请求转发代理服务器了。

其次,我们需要分别在 IOS 和 Android 上安装相关证书,这样 Proxyman 也能够充当移动端的请求转发代理服务器了。

在移动端浏览器上访问  http://proxy.man/ssl  时,会发现请求不了,此时我们复制该链接后在浏览器中打开,就能正确下载了 .pem 文件了。接下来,将文件分别传送至 IOS 或 Android 两个测试机上,就能在手机上正确安装了。

设置代理
以 Android 为例,我们在网络管理中打开 wifi,确保该 wifi 和 PC 正在连接的 wifi 一致,在 wifi 详情中找到 “代理” 相关选项,点击手动设置,将 Proxyman 上看到的 IP 和端口对应着输入即可。

Flutter 项目中的设置
在实际调试中,会发现用 Flutter 构建的 APP 无法通过 Proxyman 进行网络请求拦截,这是因为 Flutter 使用了自己的网络引擎,并且在底层实现了自己的网络协议栈, Flutter 应用的网络请求不会经过系统级别的网络栈,而是由 Flutter 框架自身处理的网络请求,因此可能无法被一些常规的代理工具直接捕获和拦截。

面对这样的问题,可以使用 Flutter 内置的 http 请求库(如 Dio 或 Http)或者自定义的网络请求库,并在应用中设置拦截器,以便在请求发出前或请求返回后进行处理。除此之外,可以借助第三方插件来帮忙处理这方面的工作。在项目中,我用的是 http_proxy 这个插件。


// 堆代码 duidaima.com
// main.dart
void setProxy() async {
  if ([EnvInfo.production, EnvInfo.stage].contains(Env.envConfig.name)) return;
  // 这是 Flutter 框架的初始化方法,确保 Flutter 框架已经初始化完毕,以便后续的操作可以正常执行
  WidgetsFlutterBinding.ensureInitialized();
  // 设置代理
  HttpProxy httpProxy = await HttpProxy.createHttpProxy();
  HttpOverrides.global=httpProxy;
}

void main() async {
  setProxy()
}
至此,我们就完成了抓包的整个环境搭建,接下来就可以在调试中发起一个请求,我们就可以在 Proxyman 上看到对应的请求了。

用户评论