0

我正在尝试使用 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 标头,Ktor 会发现令牌需要刷新并自动执行。但是,从不触发 refreshTokens 块。

有人知道为什么会这样吗?我会很感激任何帮助:)

4

1 回答 1

0

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

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

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

于 2022-02-15T09:18:20.603 回答