为 iOS Http 客户端刷新 Ktor 中的授权令牌

Refresh auth token in Ktor for iOS Http client

我有一个 KMM 项目,其中我一直在使用 Ktor 进行 API 调用。我有一个要求,如果它们已过期,我需要在刷新令牌的帮助下更新我的访问令牌。基本上我只需要在我的 Ktor 客户端中添加一个身份验证模块。不,我已经完成所有 Ktor documentation 并在我的 KMM 中添加了 Auth 模块。

现在,当我在我的 http 客户端中添加 auth 模块时,它会成功添加,并且每当我从任何 API 收到 UnAuthorized 用户错误时,它都会调用我的刷新令牌 API。问题是即使它调用我的刷新令牌 API 但在刷新令牌成功时它不会调用另一个 API 我从中收到 UnAuthorized 用户错误。

它在 Android 中按预期工作,但唯一的问题是在 iOS 客户端中。

预期(在 Android Http 客户端中工作正常):-

我面临的问题:-

HttpClient 对于 iOS :-

actual class HttpBaseClient {

    actual val tokenClient = HttpClient {
        defaultRequest {
            host = ApiEndPoints.Base.url
            url {
                protocol = URLProtocol.HTTPS
            }
            contentType(ContentType.Application.Json)
            header(CONNECTION, CLOSE)
        }
        install(JsonFeature) {
            val json = kotlinx.serialization.json.Json {
                ignoreUnknownKeys = true
                coerceInputValues = true
            }
            serializer = KotlinxSerializer(json)
        }
    }

    actual val httpClient: HttpClient = HttpClient {
        defaultRequest {
            host = ApiEndPoints.Base.url
            url {
                protocol = URLProtocol.HTTPS
            }
            contentType(ContentType.Application.Json)
            header(CONNECTION, CLOSE)
        }
        // Validate Response
        expectSuccess = false
        // Install Auth
        install(Auth) {
            lateinit var refreshTokenInfo : LoginResponse
            bearer {
                refreshTokens { unauthorizedResponse: HttpResponse ->
                    NSLog("Unauthorized response received")
                    BaseAPIClass().refreshAuthToken().fold(
                        failed = {
                            // On Failed
                            NSLog("Token Failed"). // No Callback received here
                        },
                        succeeded = { response ->
                            refreshTokenInfo = response
                            NSLog("Token Updated") // No Callback received here even when API is success
                        }
                    )
                    BearerTokens(
                        accessToken = refreshTokenInfo.accessToken ?: "",
                        refreshToken = refreshTokenInfo.refreshToken ?: ""
                    )
                }
            }
        }
        // JSON Deserializer
        install(JsonFeature) {
            val json = kotlinx.serialization.json.Json {
                ignoreUnknownKeys = true
                coerceInputValues = true
            }
            serializer = KotlinxSerializer(json)
        }

Android 客户端(几乎相同):-

actual class HttpBaseClient {

    actual val tokenClient = HttpClient {
        defaultRequest {
            host = ApiEndPoints.Base.url
            url {
                protocol = URLProtocol.HTTPS
            }
            contentType(ContentType.Application.Json)
            header(CONNECTION, CLOSE)
        }
        install(JsonFeature) {
            val json = kotlinx.serialization.json.Json {
                ignoreUnknownKeys = true
                coerceInputValues = true
            }
            serializer = KotlinxSerializer(json)
        }
        install(Logging) {
            logger = Logger.DEFAULT
            level = LogLevel.ALL
        }
    }

    actual val httpClient: HttpClient = HttpClient {
        defaultRequest {
            host = ApiEndPoints.Base.url
            url {
                protocol = URLProtocol.HTTPS
            }
            contentType(ContentType.Application.Json)
            header(CONNECTION, CLOSE)
        }
        // Validate Response
        expectSuccess = false
        //Authentication
        install(Auth) {
            lateinit var refreshTokenInfo : LoginResponse
            bearer {
                refreshTokens { unauthorizedResponse: HttpResponse ->
                    BaseAPIClass().refreshAuthToken().fold(
                        failed = {
                            // On Failed
                        },
                        succeeded = { response ->
                            refreshTokenInfo = response
                        }
                    )
                    BearerTokens(
                        accessToken = refreshTokenInfo.accessToken ?: "",
                        refreshToken = refreshTokenInfo.refreshToken ?: ""
                    )
                }
            }
        }

Ktor 版本:- 1.6.2(阅读 this issue 后也尝试了 1.6.4,但没有成功)

我得到了这个工作只是错误是在这段代码:-

succeeded = { response ->
                        refreshTokenInfo = response
                        NSLog("Token Updated") // No Callback received here even when API is success
                    }

我不确定为什么,但是将响应分配给我的 lateinit var refreshTokenInfo 是这里的主要问题。我删除了它并将我的代码更新为

refreshTokens { unauthorizedResponse: HttpResponse ->
                BaseAPIClass().refreshAuthToken().fold(
                    failed = {
                        // On Failed
                        return@refreshTokens BearerTokens(
                            accessToken = "",
                            refreshToken = ""
                        )
                    },
                    succeeded = { response ->
                      return@refreshTokens BearerTokens(
                            accessToken = response.accessToken ?: "",
                            refreshToken = response.refreshToken ?: ""
                        )
                    }
                )
            }

这行得通。

我也提出了这个问题here你可以看一下详情