为 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 客户端中工作正常):-
- 调用任何 API -> 如果收到任何
UnAuthorized
用户错误调用刷新令牌 API -> onSuccess of refresh token API -> 调用第一个 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(阅读 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你可以看一下详情
我有一个 KMM 项目,其中我一直在使用 Ktor 进行 API 调用。我有一个要求,如果它们已过期,我需要在刷新令牌的帮助下更新我的访问令牌。基本上我只需要在我的 Ktor 客户端中添加一个身份验证模块。不,我已经完成所有 Ktor documentation 并在我的 KMM 中添加了 Auth
模块。
现在,当我在我的 http 客户端中添加 auth 模块时,它会成功添加,并且每当我从任何 API 收到 UnAuthorized
用户错误时,它都会调用我的刷新令牌 API。问题是即使它调用我的刷新令牌 API 但在刷新令牌成功时它不会调用另一个 API 我从中收到 UnAuthorized
用户错误。
它在 Android 中按预期工作,但唯一的问题是在 iOS 客户端中。
预期(在 Android Http 客户端中工作正常):-
- 调用任何 API -> 如果收到任何
UnAuthorized
用户错误调用刷新令牌 API -> onSuccess of refresh token API -> 调用第一个 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(阅读 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你可以看一下详情