Android Ktor中Token刷新后API重试失败的检测与处理方法
解决Ktor刷新Token后重试请求失败的登出处理问题
要检测刷新Token后的重试请求是否失败,核心思路是给刷新Token后的重试请求打上标记,然后在响应校验器中识别这个标记,一旦标记存在且请求失败,就执行登出操作。Ktor提供的AttributeKey机制可以安全地给请求附加自定义元数据,这是最符合Ktor idiomatic风格的实现方式。
实现步骤
1. 定义自定义属性键
先定义一个全局的AttributeKey,用于标记请求是否是Token刷新后的重试请求:
// 标记该请求是Token刷新后的重试请求 private val RETRIED_AFTER_TOKEN_REFRESH = AttributeKey<Boolean>("RetriedAfterTokenRefresh")
2. 修改Bearer认证配置,给重试请求打标记
在bearer认证的sendAuthenticatedRequest回调中,拦截所有带Bearer Token的请求,当请求是刷新Token后的重试请求时,为其添加标记:
val client = HttpClient { install(Auth) { bearer { // 拦截带Token的请求,给刷新后的重试请求打标记 sendAuthenticatedRequest { request, tokens -> // 仅当Token存在(说明是刷新后重试)且未标记过时,添加标记 if (tokens != null && !request.attributes.contains(RETRIED_AFTER_TOKEN_REFRESH)) { request.attributes.put(RETRIED_AFTER_TOKEN_REFRESH, true) } // 继续执行请求流程 proceed(request, tokens) } refreshTokens { val newToken = refreshAccessToken() // 调用刷新Token的API if (newToken != null) { TokenStorage.saveTokens(newToken) // 保存新Token newToken } else { // 刷新Token失败直接执行登出 logOutUser() null } } } } // 其他配置... }
3. 在响应校验器中检测标记并处理登出
在HttpResponseValidator中,检查当前失败请求是否带有重试标记,若存在则执行登出操作:
HttpResponseValidator { handleResponseExceptionWithRequest { exception, request -> when (exception) { is ResponseException -> { val statusCode = exception.response.status val (value, description) = HttpStatusCode.fromValue(statusCode.value) val vivekException = runCatching { Json.decodeFromString<VivekException>(exception.response.bodyAsText()) }.getOrElse { e -> VivekException( value, description, serverMessage = "Failed to parse server error: ${e.message}" ) } // 检测是否是刷新Token后的重试请求失败 if (request.attributes.contains(RETRIED_AFTER_TOKEN_REFRESH)) { logOutUser() // 重试仍失败,执行登出 } throw vivekException } else -> throw VivekException(null, null, serverMessage = exception.message) } } }
方案说明
- 该方案利用Ktor的
AttributeKey实现请求级别的元数据跟踪,每个请求的attributes都是独立的,不会有并发问题,完全符合Ktor的设计理念。 - 仅当刷新Token成功后发起的重试请求失败时,才会触发登出,避免了第一次请求返回401就直接登出的误判。
- 若刷新Token本身失败,
refreshTokens块中已经处理了登出逻辑,覆盖了所有异常场景。
内容的提问来源于stack exchange,提问作者Compose Learner
相关产品推荐
相关产品推荐

