我有一个 KMM 项目,其中我一直在使用 Ktor 进行 API 调用。我有一个要求,如果它们已过期,我需要在刷新令牌的帮助下更新我的访问令牌。基本上我只需要在我的 Ktor 客户端中添加一个身份验证模块。不,我已经浏览了所有Ktor 文档Auth
并在我的 KMM 中添加了模块。
现在,当我在我的 http 客户端中添加身份验证模块时,它会成功添加,并且每当我UnAuthorized
从任何 API 收到用户错误时,它都会调用我的刷新令牌 API。问题是即使它调用了我的刷新令牌 API,但在刷新令牌成功时,它不会调用我收到UnAuthorized
用户错误的其他 API。
它在 Android 中按预期工作,但唯一的问题是在 iOS 客户端中。
预期(在 Android Http 客户端中工作正常):-
- 调用任何 API -> 如果收到任何
UnAuthorized
用户错误调用刷新令牌 API -> 刷新令牌 API 的 onSuccess -> 使用更新的刷新令牌再次调用第一个 API。
我面临的问题:-
- 调用任何 API -> 如果收到任何
UnAuthorized
用户错误,则调用刷新令牌 API -> onSuccess of refresh token API -> 在此步骤中什么也不做,只会从第一个 API 引发未经授权的用户错误。
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(在阅读此问题后也尝试了 1.6.4,但没有成功)