OkHttp Authenticator获取新Token后陷入循环问题排查
1. 获取Token的请求被重复拦截重试
你的getNewToken()请求会被AuthInterceptor自动添加旧Token,若该请求返回401(比如旧Token已失效),Authenticator会再次触发重试,导致无限循环调用getNewToken(),最终触发请求次数超限。
解决方法:在Authenticator和AuthInterceptor中跳过获取Token的接口,不对其进行鉴权处理:
// 修改AuthAuthenticator override fun authenticate(route: Route?, response: Response): Request? { // 跳过获取Token的请求,避免循环重试 val requestUrl = response.request.url.toString() if (requestUrl.contains("getAuthToken")) { // 替换为你实际的Token接口路径 return null } return runBlocking { val apiResponse = getNewToken() if (apiResponse.isSuccessful) { val accessToken = apiResponse.body()?.token ?: return@runBlocking null val expireTime = apiResponse.body()?.expireTime ?: return@runBlocking null sessionManager.saveToken(accessToken, expireTime) response.request.newBuilder() .header(ApiValues.authHeaderKey, "${ApiValues.authHeaderValue}$accessToken") .build() } else { null } } }
// 修改AuthInterceptor override fun intercept(chain: Interceptor.Chain): Response { val request = chain.request() // 跳过获取Token的请求,不添加鉴权Header val requestUrl = request.url.toString() if (requestUrl.contains("getAuthToken")) { // 替换为实际路径 return chain.proceed(request) } val token = runBlocking { sessionManager.getToken().first() } val newRequest = request.newBuilder() .addHeader(ApiValues.authHeaderKey, ApiValues.authHeaderValue.plus(token)) .build() return chain.proceed(newRequest) }
2. 鉴权Header格式不匹配
你的AuthInterceptor使用ApiValues常量构建鉴权Header,但Authenticator中硬编码了"Authorization", "Bearer $accessToken",两处Header的键或格式可能不一致,导致新Token添加后请求依然返回401,触发循环。
解决方法:统一两处的Header配置,直接复用ApiValues中的常量:
// Authenticator中修改Header设置 response.request.newBuilder() .header(ApiValues.authHeaderKey, "${ApiValues.authHeaderValue}$accessToken") .build()
3. 未限制重试次数
OkHttp的Authenticator默认会多次重试,即便新Token本身无效(比如获取Token的接口返回的Token不符合Twitch要求),也会持续重试直到触发请求次数超限。
解决方法:在Authenticator中添加重试次数限制,超过阈值则终止循环:
// 在AuthAuthenticator的authenticate方法开头添加 if (response.retryCount >= 1) { // 限制最多重试1次 return null }
4. SessionManager的Token更新异常
如果sessionManager.saveToken没有正确更新Token数据流,AuthInterceptor获取到的可能还是旧Token,导致重试请求依然使用无效Token,触发401循环。
验证与修复:在saveToken后打印新Token,同时在AuthInterceptor中打印获取到的Token,确认两者是否一致;若不一致,检查SessionManager中getToken()返回的Flow是否正确发送新值。
内容的提问来源于stack exchange,提问作者ErneSalazar238

