移动端请求如何确保 HTTPS 加密不被中间人攻击?

程序猿鑫哲 阅读 3

我们 App 的 H5 页面通过 fetch 发起 API 请求,虽然用了 HTTPS,但听说还是可能被抓包或中间人攻击。我试过在请求头加自定义 token:headers: { 'X-Token': 'xxx' },但感觉这并不能防抓包。有没有更靠谱的方式?比如证书绑定或者公钥校验?

看到有些资料提到 SSL Pinning,但不确定在纯前端 H5 里能不能实现。现在用的是 Vue3 + Vite,有推荐的方案吗?

我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
晨妍🍀
这个问题挺常见的,我先泼盆冷水:纯前端 H5 基本上做不到真正的 SSL Pinning。

SSL Pinning 的原理是把服务器证书或公钥"钉"在客户端,每次请求时校验。但 WebView 里跑的网页没有权限访问系统证书库,也没有 API 来做证书校验。所以网上那些前端实现 SSL Pinning 的方案基本都是半吊子,意义不大。

真正能打的方案就这几个:

方案一:在原生 App 端做证书绑定(最靠谱)

如果你们的 H5 是跑在 App 的 WebView 里,最佳实践是在原生 iOS/Android 那层做证书绑定。iOS 有 NSURLSession 的 challenge 回调,Android 有 OkHttp 的 CertificatePinner,直接在 native 代码里校验证书指纹。H5 本身是防不住的,得靠宿主 App 来保护。

方案二:双向认证(mTLS)

服务器要求客户端也提供证书,双向验证。但这需要 App 内置客户端证书文件,实现成本偏高,一般支付类场景才会用。

方案三:前端能做的有限防护

在 Vue3 里可以加一些检测手段,比如检查是否走了代理、warn 用户当前网络不安全,但这些只能吓唬人,专业抓包工具绑个证书就能绕过。

// 简单检测下是否开了代理(仅作提示)
const isProxy = await fetch('/api/health', {
method: 'HEAD'
}).catch(() => true);

if (isProxy) {
console.warn('检测到可能存在代理');
}


方案四:后端层面加固

这个比前端靠谱多了——在请求里加签名。比如每次 API 调用带上 timestamp + nonce + signature,服务器校验签名是否合法。即使被抓包,攻击者也很难伪造有效签名。微信支付、支付宝的接口都是这么干的。

总结下:

如果你们能改 App 代码,优先在原生层做证书绑定,这是最直接的。如果只能改 H5,那就靠后端签名 + 前端简单检测凑合着。单纯加个 X-Token 确实防不住专业抓包,token 本身也是明文传输的。
点赞
2026-03-12 17:17