Retrofit中使用变量Token的Authorization认证失效求助
问题解决思路
你的代码核心问题出在静态Retrofit实例的复用逻辑,以及可能的Token格式问题,以下是具体修复步骤:
1. 修复静态Retrofit实例的复用问题
你定义的retrofit_api是静态变量,只会在第一次调用时初始化。后续传入新Token时,不会重新创建OkHttpClient和Retrofit实例,导致请求头始终使用第一次的Token,这是403的关键原因。
方案一:每次调用创建新Retrofit实例(简单直接)
public static Retrofit getRetrofitInstanceForAPIGateway(String token) { Log.e("RetrofitClient", "Token: " + token); // 检查并补全Token格式(多数API要求Bearer前缀) if (!token.startsWith("Bearer ")) { token = "Bearer " + token; } OkHttpClient client = new OkHttpClient.Builder().addInterceptor(chain -> { Request newRequest = chain.request().newBuilder() .header("Authorization", token) // 用header替代addHeader,避免重复添加请求头 .build(); return chain.proceed(newRequest); }).build(); // 不再复用静态实例,每次生成新的Retrofit对象 return new Retrofit.Builder() .client(client) .baseUrl(API_GATEWAY_BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); }
方案二:保留单例,动态更新Token(性能更优)
如果想复用Retrofit和OkHttpClient实例,可将Token存入拦截器动态更新:
// 定义可动态更新Token的拦截器 private static class AuthInterceptor implements Interceptor { private volatile String token; public void setToken(String token) { if (!token.startsWith("Bearer ")) { this.token = "Bearer " + token; } else { this.token = token; } } @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); if (token != null) { request = request.newBuilder() .header("Authorization", token) .build(); } return chain.proceed(request); } } // 静态变量改为拦截器和Retrofit实例 private static AuthInterceptor authInterceptor = new AuthInterceptor(); private static Retrofit retrofit_api; public static Retrofit getRetrofitInstanceForAPIGateway(String token) { Log.e("RetrofitClient", "Token: " + token); // 先更新拦截器的Token authInterceptor.setToken(token); if (retrofit_api == null) { OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(authInterceptor) .build(); retrofit_api = new Retrofit.Builder() .client(client) .baseUrl(API_GATEWAY_BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); } return retrofit_api; }
2. 验证Token参数的正确性
- 对比打印的
token和硬编码字符串,检查是否完全一致(包括前后空格、大小写、特殊字符)。 - 确认API是否要求
Authorization头带Bearer前缀,很多接口会因为缺少前缀返回403。
3. 用日志拦截器排查实际请求头
添加OkHttp日志拦截器,查看实际发送的请求头与硬编码时的差异:
// 先添加依赖(若未添加) // implementation 'com.squareup.okhttp3:logging-interceptor:4.11.0' // 创建OkHttpClient时加入日志拦截器 HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(); loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS); OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(loggingInterceptor) .addInterceptor(authInterceptor) // 或你的自定义拦截器 .build();
通过日志可直接看到发送的Authorization头内容,快速定位问题。
内容的提问来源于stack exchange,提问作者njugran
相关产品推荐
相关产品推荐

