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

在Jetpack Compose Android应用中加载网页时如何正确传递Token

解决Android WebView加载授权页面跳转到登录页的问题

你的核心问题是页面先加载再注入Token,导致页面初始化时后端未检测到有效授权,直接跳转到登录页。以下是几种可行的修复方案:

方案1:通过请求头携带Token(推荐)

多数后端服务会优先校验请求头中的Token(比如Authorization: Bearer <token>),这种方式比JS注入更安全可靠。

val token = "zxcvffffgggh....."
val url = "https://abcd.com/training"

AndroidView(factory = { context ->
    WebView(context).apply {
        layoutParams = ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT
        )
        webViewClient = object : WebViewClient() {
            override fun shouldInterceptRequest(
                view: WebView?,
                request: WebResourceRequest?
            ): WebResourceResponse? {
                request?.let {
                    val newRequest = WebRequest.Builder(it.url)
                    // 根据后端要求设置请求头,常见格式是Bearer Token
                    newRequest.addHeader("Authorization", "Bearer $token")
                    // 复制原请求的其他头信息
                    it.requestHeaders.forEach { (key, value) ->
                        newRequest.addHeader(key, value)
                    }
                    return super.shouldInterceptRequest(view, newRequest.build())
                }
                return super.shouldInterceptRequest(view, request)
            }
        }
        settings.cacheMode = WebSettings.LOAD_NO_CACHE
        settings.domStorageEnabled = true
        settings.javaScriptEnabled = true

        loadUrl(url)
    }
})

方案2:先注入Token再加载页面

确保页面加载前,Token已经注入到window对象中,需要监听WebView的初始化完成事件:

val token = "zxcvffffgggh....."
val url = "https://abcd.com/training"

AndroidView(factory = { context ->
    WebView(context).apply {
        layoutParams = ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT
        )
        webViewClient = object : WebViewClient() {
            override fun onPageFinished(view: WebView?, url: String?) {
                super.onPageFinished(view, url)
            }
        }
        settings.cacheMode = WebSettings.LOAD_NO_CACHE
        settings.domStorageEnabled = true
        settings.javaScriptEnabled = true

        // 先注入Token,再加载页面
        post {
            evaluateJavascript("window.token = '$token';") {
                // 注入完成后加载目标页面
                loadUrl(url)
            }
        }
    }
})

方案3:通过Cookie携带Token

如果后端是通过Cookie校验授权,可以直接设置Cookie:

val token = "zxcvffffgggh....."
val url = "https://abcd.com/training"
val domain = "abcd.com"

AndroidView(factory = { context ->
    WebView(context).apply {
        layoutParams = ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT
        )
        webViewClient = WebViewClient()
        settings.cacheMode = WebSettings.LOAD_NO_CACHE
        settings.domStorageEnabled = true
        settings.javaScriptEnabled = true

        // 设置Cookie,根据后端要求的Cookie名调整
        CookieManager.getInstance().apply {
            setAcceptCookie(true)
            setCookie(domain, "auth_token=$token")
            flush()
        }

        loadUrl(url)
    }
})

额外注意事项

  • 确认后端校验Token的方式:是请求头、Cookie还是前端JS变量,针对性选择方案。
  • 检查Token是否有效:可以用Postman直接请求https://abcd.com/training并携带Token,验证Token是否过期或权限不足。
  • 关闭WebView缓存:你的代码已经设置LOAD_NO_CACHE,确保不会加载旧的未授权页面缓存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 01:45:27