本文适用于:WebView 混合开发、Hybrid App、Android+iOS + H5、App 内嵌业务、前端 axios 调接口的项目。
核心目标:搞清楚 Token 是否能给前端、哪些接口让 H5 调、哪些必须走原生,以及最安全的架构是什么。
一、先说结论(最重要)
对于所有 Hybrid 项目,可以直接采用下面这套三段式分级策略:
① 不需要登录的接口(公共接口) → H5 自己 axios,无需 Token
例如:
Banner、文章列表、活动页内容
商品展示页
公共配置接口
这些接口本身没敏感风险,让前端自己请求,最省心。
② 需要登录但风险一般的接口(普通业务) → 统一走原生网络层(App.request),H5 不拿 Token
例如:
查询个人资料
普通订单列表
普通业务提交
这些接口需要鉴权,但不允许 H5 拿到 token,所以:
H5 调 JSBridge → 原生带 token 发出去 → 结果回调给 H5。
H5 完全看不到 token,更安全。
③ 高风险接口(资产 / 支付 / 关键控制) → 必须原生代发 + 内部加签名
例如:
- 登录 / Token 刷新
- 下单、支付
- 用户资产、账户操作
- 任何高价值动作(例如机器人控制指令)
这类接口必须:
- H5 不得发请求
- H5 不得获取 Token
- 统一
App.request() 原生这里可以做:
- Token 注入
- 签名
- TLS Pinning
- 风控 / 设备ID / 限制算法
这是企业级安全架构的基本线。
二、为什么不能让 H5 直接拿 Token?
Hybrid 中最常见的两个误区是:
误区 1:axios + Authorization 就很安全?——并不
axios.get('/user/profile', { headers: { Authorization: `Bearer ${window.APP_TOKEN}` } });只要 Token 暴露在:
- window
- JS 全局
- localStorage
- 任意 JS 环境
就意味着:XSS、第三方脚本、被注入脚本都可以拿到 Token。
即便配合 CookieManager 也一样,因为:
只要 Token 不带 HttpOnly,JS 就能读,安全性 = 一般。
误区 2:CookieManager 写 Token 更安全?——其实也不
很多人会写:
cookieManager.setCookie("https://m.xxx.com", "token=abc")
三、真正安全的思路:不是保护 Token,而是不给 Token
这里是全文核心理念:
只要 H5 能调后端,H5 就必须带鉴权;
H5 只要带鉴权,就会暴露鉴权凭证;
因此最安全的办法是:H5 不调后端、让原生代发。
这就是为什么最终落地要:
无 Token 的接口 → H5 直接 axios
有 Token 的接口 → 原生代发,不给 H5 Token
而不是纠结 Token 放 Cookie 还是放 Header。
四、落地的代码架构(非常清晰)
① H5:公共接口
axios.get('/config/public').then(res => {}); axios.get('/article/list').then(res => {});② H5:重要接口统一通过 JSBridge 调原生
window.App.request({ url: '/user/profile', method: 'GET', data: {}, success(res) { console.log(res); }, fail(err) { console.error(err); } });H5 不接触 Token。
③ 原生:统一网络网关(Kotlin 示例)
@JavascriptInterface fun request(json: String) { val req = parse(json) val token = tokenStore.getAccessToken() val httpReq = buildRequest(baseUrl + req.url) { header("Authorization", "Bearer $token") header("Device-Id", deviceId) // 原生还能加签名、TLS Pinning、安全参数 } client.newCall(httpReq).enqueue(object : Callback { override fun onResponse(...) { callbackToJs(req.callbackId, bodyString) } override fun onFailure(...) { callbackToJsError(req.callbackId, errorMsg) } }) }五、整套策略的优点
1)H5 世界里没有 Token —— 安全性最大化
JS 拿不到 token → XSS 也拿不到 token → 攻击面小。
2)前端开发简单
公共接口直接 axios
登录态接口统一 App.request,不用管 token 注入
3)后端风控可以做得更强
因为所有带 token 的请求都来自原生网络层:
可以确定 UA、Device ID、App Version
可以确定证书是否校验
可以签名
可以走统一安全通道
这些 H5 都做不到。
4)架构层次分明、非常易维护
一句话总结:
H5 = UI层,负责界面与业务表达
原生 = 安全层 + 能力层,负责鉴权、Token、安全请求
这是今天最推荐的 Hybrid 结构。
六、整篇文章总结(核心一句话版)
**把接口分两类:
不需要 Token 的 → H5 自己 axios;
需要 Token 的 → 原生代发,H5 不接触 Token。不要让 H5 拿 Token,这才是 Hybrid 的最佳实践。**