You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 00:10:35