鱼肚的博客

技术宅改变世界

前端调试之网络代理

说到前端调试,脑海中是不是自然地就想到了源代码,想到开发环境等等概念?

它们是必需的吗?

移动应用调试时常有抓包的概念,它是什么?只能用来看日志吗?

本文带你了解一个新的前端应用调试思路,从工具应用到原理解析。希望能对读者有所启发,起到抛砖引玉的作用。

多环境的困局

软件开发过程中,为了保证质量,往往会将应用部署多个备份。即我们所熟知的生产环境、灰度环境、测试环境、开发环境等。

相应地,软件测试的过程也会分成多个阶段进行。

一般来说,测试人员会在各个不同的环境进行测试,但是开发人员总是会在本地进行修改。这个差异大多数时候不是什么问题,因为相同的代码会有相同的表现。

但是有的时候事情没那么简单,我们或多或少都遇到过一些这样的场景:

  1. 生产环境或测试环境能复现的问题,在开发人员本地环境中无法复现(如需要特定数据)。
  2. 开发环境、测试环境中上下游系统不稳定,导致无法正常使用。
  3. 开发环境、测试环境中上下游系统改版,无法保证与生产环境一致。
  4. 线上应用为微服务集群,难以在本地完美复制。

应用的架构越是复杂,想在本地搭建出一套100%一致的系统,就越困难。

试想下一个前端微应用,嵌入在门户首页中,本地运行正常,即使在生产环境独立访问也是正常的,只有嵌入在门户首页的时候才会出问题。这种情况的调试难度是较高的,使用传统方案很难解决,往往要靠猜测来实现。

这个时候,如果能随时将代码部署到生产环境进行调试,是不是就很容易啦?

当然,我们都知道这样是不现实,不负责的做法。生产环境不能用于调试。

然而,前端不一样!

这里,就需要提一下前端和后端应用的不同之处了。

前端与后端的区别

这里所指的前端,均为狭义前端,即运行在浏览器或原生应用WebView之中的,由HTML/CSS/JS/WASM等组成的Web应用。不包含Node.js及原生app。

前端与后端的区别,在于生产环境和运行环境的不统一。

后端环境

对于后端应用来说,生产环境即运行环境,现在一般是容器化的集群部署,通过Docker或类似工具提供稳定的运行环境。

虽然很多后端应用会有集群,分布式部署。但是一般来说,各个副本之间没有差别,代码和运行环境完全一致。

甚至很多无状态的后端应用,可以随时无缝替换彼此。

总结一下:后端应用运行在服务端,程序变更之后,会影响到很多用户。

前端环境

前端在部署上也类似于后端,无论是单节点还是多节点,返回的 HTML/CSS/JS等静态资源是始终一致的。

但是它的运行环境却千差万别。

有的运行在Chrome中,有的在Firefox中,有的在桌面端,有的在移动端。即使是同一个浏览器,还有不同版本的差别。

它们可以归结为一个环境:用户端。

因为是用户自己的环境,所以在它的上面再怎么折腾,也影响不到其它的用户。

这就使得我们可以直接调试 “生产环境”!

具体怎么做呢?这就回到了本文的题目中来了,网络代理。

网络代理调试

在说这个之前,先看一个“中间人攻击(MITM)”的示意图。

Man-in-the-middle attacks (MITM) and how to avoid them

图片来自于 https://dpsvdv74uwwos.cloudfront.net/statics/img/ogimage/man-in-the-middle-attack-how-avoid.png,侵删

网络代理调试,运用的就是这个攻击的原理。

简单来说,步骤如下:

  1. 通过上述的攻击原理,搭建一个“中间人”角色
  2. 篡改客户端(浏览器、APP等)的网络请求,使其指向 “中间人”
  3. 在“中间人”角色中,提供本地构建的代码用于调试。

那么具体来说有什么手段呢?

网络代理的手段

根据运行环境的不同,可采用的手段也不完全相同。

主要分为以下两类:

  1. 基于抓包工具实现的中间人攻击,适用于所有场景。特点是功能强,但配置复杂,易用性稍差。
  2. 基于浏览器插件实现的中间人攻击,适用于Chrome、Firefox浏览器及其它兼容Chrome插件的浏览器。特点是配置简单,但需要了解一些坑点,某些情况下需要代码配合。

两者的原理也相差较大,下面我分别介绍下对应的工具及原理。

基于抓包工具的中间人攻击

抓包工具有不少,有的需要付费使用,如老牌的Charles,有些虽然提供收费模式,但免费功能也凑合能用,如Mac上的ProxyMan。

它们的特点是:

  1. 需要安装证书才能攻击 HTTPS 资源。
  2. 浏览器端无感知,不需要修改代码配合。

这里我主要介绍ProxyMan。

ProxyMan 是一个macOS上的抓包工具,可以监控请求列表。

Proxyman Dashboard on macOS

也可以捕捉请求并设置自定义响应,映射到本地文件。

img

还可以映射到另一个URL:

Map Remote

基于浏览器插件的中间人攻击

因为一些安全方面的考量,浏览器插件并不能实现系统级别网络代理带来的无感知体验。

但是它可以为网络请求做重定向。

即虽然浏览器插件能篡改网络接口,但是在DevTools中会有记录,且会受到各种浏览器自身的限制,如混合内容限制等。

所以它的特点是:

  1. 存在混合内容限制(127.0.0.1除外)。
  2. 存在跨域限制。
  3. 对于前端应用的 webpack 分片,需要特殊处理(publicPath)。
  4. 配置和切换较为简单

浏览器插件可以使用 Resource Override。

img

网络安全

通过上面的例子也可以看出,在网络无保障的情况下,前端看到的内容很可能是不安全的。

这提醒我们,在安装证书,尤其是CA证书时,一定要谨慎。

不然很可能会受到中间人攻击而不自知。


以上就是通过网络代理(转发)调试前端应用的所有内容。