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

如何用Retrofit2 Interceptor实现先获取Cookie再调用目标API?

使用Retrofit2 Interceptor优化Cookie验证流程

嘿,我太懂你现在的困扰了——每次调用API都要嵌套一层Cookie验证的请求,重复代码堆得像山,不仅写着烦,后期维护也头疼。用Retrofit的Interceptor就能把这个验证逻辑彻底抽离出来,让业务请求和Cookie验证完全解耦,再也不用写那些嵌套的Callback了!

核心思路

Interceptor就像请求的“前置过滤器”,所有经过Retrofit的请求都会先经过它。我们可以在这里统一处理Cookie验证:

  • 拦截需要验证的请求
  • 同步验证当前Cookie的有效性
  • 验证通过就放行原请求;不通过就触发登录(或刷新Cookie),中断当前请求

1. 编写Cookie验证Interceptor

注意:Interceptor的intercept方法是阻塞式的,所以Cookie验证要用同步请求,不能用异步的enqueue。另外UI操作要切回主线程,因为Interceptor默认在子线程执行。

public class AuthCookieInterceptor implements Interceptor {
    private final AuthCookieModel authCookieModel;
    private final Context context;

    public AuthCookieInterceptor(AuthCookieModel authCookieModel, Context context) {
        this.authCookieModel = authCookieModel;
        this.context = context;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request originalRequest = chain.request();

        // 先同步验证Cookie有效性
        ValidateAuthCookieModel validateResult = validateCookieSync(authCookieModel.getCookie());
        if (validateResult == null || !validateResult.valid) {
            // Cookie无效,切回主线程跳登录
            ((Activity) context).runOnUiThread(this::openLogin);
            // 抛出异常中断请求,让业务层可以捕获处理
            throw new IOException("Cookie验证失败,已跳转登录");
        }

        // Cookie有效,放行原请求
        return chain.proceed(originalRequest);
    }

    // 同步调用Cookie验证API
    private ValidateAuthCookieModel validateCookieSync(String cookie) throws IOException {
        OkHttpClient tempClient = new OkHttpClient();
        Request validateRequest = new Request.Builder()
                .url(ApiUtil.VALIDATE_COOKIE_URL) // 替换成你的验证API地址
                .addHeader("Cookie", cookie)
                .build();

        Response response = tempClient.newCall(validateRequest).execute();
        if (response.isSuccessful()) {
            return new Gson().fromJson(response.body().string(), ValidateAuthCookieModel.class);
        }
        return null;
    }

    private void openLogin() {
        // 这里写你的登录页面跳转逻辑
        Intent intent = new Intent(context, LoginActivity.class);
        context.startActivity(intent);
    }
}

2. 给Retrofit配置Interceptor

把上面的Interceptor添加到Retrofit的OkHttpClient里,这样所有请求都会自动走验证流程:

OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .addInterceptor(new AuthCookieInterceptor(authCookieModel, yourContext))
        .build();

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(ApiUtil.BASE_URL)
        .client(okHttpClient)
        .addConverterFactory(GsonConverterFactory.create())
        .build();

// 创建你的API Service接口实例
ApiService apiService = retrofit.create(ApiService.class);

3. 优化后的业务请求代码

现在你原来的嵌套代码可以简化成一行,再也不用写双层Callback了:

apiService.addLike(item.getId(), mCookie).enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
        // 处理点赞成功的业务逻辑
    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
        // 可以在这里捕获Cookie验证失败的异常
        if (t instanceof IOException && t.getMessage().contains("Cookie验证失败")) {
            // 已经在Interceptor里跳了登录,这里不用重复处理
        } else {
            // 处理其他请求失败情况(比如网络错误)
        }
    }
});

额外优化小技巧

  • 跳过特定请求的验证:如果有些公共API不需要Cookie验证,可以给请求加自定义Header,在Interceptor里判断跳过:
    // Interceptor里添加判断
    if (originalRequest.header("Skip-Cookie-Validation") != null) {
        return chain.proceed(originalRequest);
    }
    
    // API接口里添加Header
    @GET("public/article")
    Call<ArticleModel> getPublicArticles(@Header("Skip-Cookie-Validation") String skip);
    
    // 调用时传"true"即可跳过验证
    apiService.getPublicArticles("true").enqueue(...);
    
  • 自动刷新Cookie:如果你的系统支持用refresh token刷新Cookie,可以在Interceptor里替换跳登录的逻辑,先尝试刷新Cookie,成功后自动重试原请求,提升用户体验。

内容的提问来源于stack exchange,提问作者Carlos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:35:21