You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Android WebView中拦截HTTP Form Data获取认证令牌

Android WebView 提取Form Data认证令牌实现方案

Android 原生WebView 没有提供和iOS NavigationAction.httpBody 对等的直接获取POST请求Body的系统API,可通过以下两种稳定方案实现需求,核心逻辑和iOS端一致:先匹配目标回调URL,再提取对应POST请求的Form Data解析令牌。


方案1:注入JavaScript监听表单提交(兼容性最好,实现成本最低)

适合仅需要监听登录表单提交获取令牌的场景,适配全Android版本。

实现步骤:

  1. 开启WebView的JS权限,配置JS交互接口
// 开启JS支持
webView.settings.javaScriptEnabled = true
// 注入原生交互接口,AndroidInterface为JS中调用的对象名
webView.addJavascriptInterface(AuthJsInterface(), "AndroidInterface")
  1. 自定义JS交互接口,接收JS传回的表单数据
class AuthJsInterface {
    @JavascriptInterface
    fun receiveFormData(formDataStr: String) {
        // formDataStr为序列化后的表单键值对,格式为key1=value1&key2=value2
        formDataStr.split("&").forEach { keyValue ->
            val (key, value) = keyValue.split("=")
            // 替换为你的认证令牌对应的参数名
            if (key == "auth_token") {
                val authToken = value.decode()
                // 拿到令牌后执行后续业务逻辑
            }
        }
    }
}
  1. 重写WebViewClient的onPageFinished回调,页面加载完成后注入表单监听JS
override fun onPageFinished(view: WebView?, url: String?) {
    super.onPageFinished(view, url)
    // 仅在登录页加载完成后注入监听代码,替换为你的登录页URL特征
    if (url?.contains("/login") == true) {
        view?.loadUrl("""
            javascript:(function(){
                // 监听页面所有表单的提交事件
                const forms = document.getElementsByTagName('form');
                for(let i=0; i<forms.length; i++){
                    forms[i].addEventListener('submit', function(e){
                        // 序列化表单数据
                        const formData = new FormData(this);
                        let dataStr = '';
                        for(const [key, value] of formData.entries()){
                            if(dataStr) dataStr += '&';
                            dataStr += encodeURIComponent(key) + '=' + encodeURIComponent(value);
                        }
                        // 传回Android原生层
                        AndroidInterface.receiveFormData(dataStr);
                    });
                }
            })();
        """.trimIndent())
    }
}

方案2:代理WebView网络请求(适合需要全量拦截请求的场景)

如果需要完全接管WebView的网络请求,可以重写shouldInterceptRequest回调,用OkHttp等网络库代理所有WebView请求,即可直接拿到POST请求的Body内容:

override fun shouldInterceptRequest(
    view: WebView?,
    request: WebResourceRequest
): WebResourceResponse? {
    // 替换为你的实际回调URL
    val targetCallbackUrl = "/identity/userAuthenticated"
    // 匹配目标POST请求
    if (request.url.toString().contains(targetCallbackUrl) && request.method == "POST") {
        // 此处通过自定义的WebView代理网络栈,拿到对应请求的Body内容
        // 解析Body中的Form Data即可提取认证令牌
    }
    return super.shouldInterceptRequest(view, request)
}

注意事项

  • 使用JS注入方案时,需要在混淆规则中保留AuthJsInterface类及其公开方法,避免被混淆后JS无法调用
  • 如果表单提交格式为multipart/form-data,需要单独编写对应格式的解析逻辑拆分内容
  • Android 12及以上版本需注意WebView的隐私权限适配,避免JS交互被系统拦截

内容的提问来源于stack exchange,提问作者Artem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 21:48:04