Ktor Client -- Bearer Token 从未刷新

Ktor Client -- Bearer Token never refreshed

我正在尝试使用 Ktor 处理不记名令牌的身份验证,但是在访问令牌失效后 refreshTokens { ... } 永远不会被触发。这是我的服务:

interface MyService {
    companion object Factory {
        fun build(getToken: GetToken, refreshToken: RefreshToken): MyService {
            return MyServiceImpl(httpClient = HttpClient(CIO) {
                install(JsonFeature) {
                    serializer = KotlinxSerializer(
                        kotlinx.serialization.json.Json {
                            ignoreUnknownKeys = true
                        }
                    )
                }
                install(Logging) {
                    logger = Logger.DEFAULT
                    level = LogLevel.HEADERS
                }
                install(Auth) {
                    lateinit var tokenInfo: TokenInfo
                    lateinit var reloadTokenInfo: TokenInfo

                    bearer {
                        refreshTokens {
                            Timber.d("token refresh")
                            val refresh = refreshToken.execute()
                            BearerTokens(
                                accessToken = refresh.accessToken,
                                refreshToken = refresh.refreshToken
                            )
                        }
                        loadTokens {
                            Timber.d("token loading")
                            val tokenInfo = getToken.execute()
                            BearerTokens(
                                accessToken = tokenInfo.accessToken,
                                refreshToken = tokenInfo.refreshToken
                            )
                        }
                    }
                }
            })
        }
    }
}

Ktor 日志:

I/System.out: 16:25:59.167 [main] INFO io.ktor.client.HttpClient - REQUEST ...
I/System.out: 16:25:59.168 [main] INFO io.ktor.client.HttpClient - METHOD: HttpMethod(value=GET)
I/System.out: 16:25:59.168 [main] INFO io.ktor.client.HttpClient - COMMON HEADERS
I/System.out: 16:25:59.168 [main] INFO io.ktor.client.HttpClient - -> Accept: application/json
I/System.out: 16:25:59.169 [main] INFO io.ktor.client.HttpClient - -> Accept-Charset: UTF-8
I/System.out: 16:25:59.169 [main] INFO io.ktor.client.HttpClient - -> Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYxMTYyNTI3LTI3NzEtNDIyOS05YzUwLWE1NDk3MmIxMzZhYSIs
I/System.out: 16:25:59.169 [main] INFO io.ktor.client.HttpClient - CONTENT HEADERS
I/System.out: 16:25:59.169 [main] INFO io.ktor.client.HttpClient - -> Content-Length: 0
I/System.out: 16:25:59.262 [main] INFO io.ktor.client.HttpClient - RESPONSE: 401 Unauthorized
I/System.out: 16:25:59.262 [main] INFO io.ktor.client.HttpClient - METHOD: HttpMethod(value=GET)
I/System.out: 16:25:59.262 [main] INFO io.ktor.client.HttpClient - FROM: ...
I/System.out: 16:25:59.263 [main] INFO io.ktor.client.HttpClient - COMMON HEADERS
I/System.out: 16:25:59.263 [main] INFO io.ktor.client.HttpClient - -> Access-Control-Allow-Credentials: true
I/System.out: 16:25:59.263 [main] INFO io.ktor.client.HttpClient - -> Access-Control-Allow-Origin: *
I/System.out: 16:25:59.263 [main] INFO io.ktor.client.HttpClient - -> Content-Length: 85
I/System.out: 16:25:59.264 [main] INFO io.ktor.client.HttpClient - -> Content-Type: application/json; charset=utf-8
I/System.out: 16:25:59.265 [main] INFO io.ktor.client.HttpClient - -> Date: Mon, 14 Feb 2022 16:25:59 GMT
I/System.out: 16:25:59.266 [main] INFO io.ktor.client.HttpClient - -> Server: Apache/2.4.29 (Ubuntu)
I/System.out: 16:25:59.266 [main] INFO io.ktor.client.HttpClient - -> X-Content-Type-Options: nosniff
I/System.out: 16:25:59.266 [main] INFO io.ktor.client.HttpClient - -> X-Powered-By: Express
I/System.out: 16:25:59.267 [main] INFO io.ktor.client.HttpClient - -> www-authenticate: Bearer

我发现很多帖子都说如果服务器响应代码 401 和 www-authenticate header,Ktor 会发现令牌需要刷新并自动执行。但是,永远不会触发 refreshTokens 块。

有人知道为什么会这样吗?如果有任何帮助,我将不胜感激:)

不调用 refreshTokens 回调的原因有多种:

  • 响应状态不是 401 Unauthorized
  • 请求的属性包含 circuitBreaker(这意味着已请求刷新令牌)
  • 没有 WWW-Authenticate header
  • WWW-Authenticate header 值格式不正确
  • 身份验证方案和领域(从 WWW-Authenticate header 值解析)未找到任何身份验证提供程序

根据问题描述中的日志,应该会调用refreshTokens回调,因为上述所有条件都满足。