0

我正在尝试让 Ktor 客户端刷新 Kotlin 多平台项目中的 Bearer 令牌。

这里有一个例子它应该如何工作。

我的 http 客户端配置代码看起来非常相似——除了获取和刷新令牌的不同请求:

...
install(Auth) {
    lateinit var tokenInfo: TokenInfo
    var refreshTokenInfo: TokenInfo

    bearer {
        loadTokens {
            val url = "https://${environment.host}:${environment.port}/oauth/login"
            tokenInfo = tokenClient.post<TokenInfo>(url) {
                contentType(ContentType.Application.Json)
                body = buildJsonObject {
                    put("username", "blah")
                    put("password", "blub")
                }
            }
            BearerTokens(
                accessToken = tokenInfo.data.access_token,
                refreshToken = tokenInfo.data.refresh_token
            )
        }
        refreshTokens {
            val url = "https://${environment.host}:${environment.port}/oauth/refresh"
            refreshTokenInfo = tokenClient.get<TokenInfo>(url) {
                contentType(ContentType.Application.Json)
                header(HttpHeaders.Authorization, tokenInfo.data.refresh_token)
            }
            BearerTokens(
                accessToken = refreshTokenInfo.data.access_token,
                refreshToken = refreshTokenInfo.data.access_token
            )
        }
    }
}

但这导致mutation attempt of frozen kotlin.native.internal.Ref. 好像不太lateinit var tokenInfo: TokenInfo喜欢

这只发生在 iOS 上。安卓工作。

(顺便说一句,我切换到了新的内存模型。但在这种情况下,这似乎无关紧要,这是同样的错误。)

4

1 回答 1

1

(A)解决方案(对我来说)是使用@Philip Dukhov 指出我的内容:Atomics(我想我应该真正阅读,而不仅仅是首先浏览它。)

所以我使用AtomicReference向 TokenInfo 添加了一个包装器:

object AtomicTokenInfo {
    val ref = AtomicReference(TokenInfo(Data(""), listOf()).freeze())

    fun storeNewValue(tokenInfo: TokenInfo) {
         ref.value = TokenInfo(tokenInfo.data, listOf()).freeze()
    }
}

然后在我的代码中使用它,例如:

    var tokenInfo = AtomicTokenInfo

    ...

    val url = "https://${environment.host}:${environment.port}/oauth/refresh"
    tokenInfo.storeNewValue(
         tokenClient.get<TokenInfo>(url) {
             contentType(ContentType.Application.Json)
             header(HttpHeaders.Authorization, tokenInfo.ref.value.data.access_token)
         }
    )

非常感谢您的评论和帮助@WhiteSpidy、@Philip Dukhov、@Aleksei Tirman

于 2021-12-17T15:17:35.060 回答