使用 OkHttp 拦截器的 Http 请求不起作用

Http requests with OkHttp Interceptor doesn't works

我正在使用带有 OkHttp 拦截器的 Retrofit 来处理 API。 拦截器向每个请求添加 cookie header。 拦截器代码:

class AddCookiesInterceptor: Interceptor {

    @Inject
    lateinit var cookiesDao: CookiesDao

    init {
        App.getAppComponent().inject(this)
    }

    @SuppressLint("CheckResult")
    override fun intercept(chain: Interceptor.Chain): Response {
        val builder = chain.request().newBuilder()
        cookiesDao.getAll()
            .subscribeOn(Schedulers.io())
            .subscribe { cookies ->
            builder.addHeader("Cookie", "JWT=" + cookies.jwt)
        }
        return chain.proceed(builder.build())
    }
}

在调试时我看到,拦截器更新请求并添加 cookie header 值,但是当服务器到达请求时它 returns 一个错误(再次 400 http 代码验证)。 如果我像这样手动将 Header 添加到请求中

    @GET("/api.tree/get_element/")
    @Headers("Content-type: application/json", "X-requested-with: XMLHttpRequest", "Cookie: jwt_value")
    fun getElementId(): Maybe<ResponseBody>

Api returns 200 个 http 代码并且有效。

Your code is not working because you are adding the header asynchronously, this is a "timeline" of what's happening in your flow:

init builder -> ask for cookies -> proceed with chain -> receive cookies dao callback -> add header to builder which has been already used

What you need to do is retrieve the cookies synchronously, to accomplish this you can use the BlockingObseervable and get something like this. Using a synchronous function won't cause any trouble since the interceptor is already 运行 on a background thread.

@SuppressLint("CheckResult")
override fun intercept(chain: Interceptor.Chain): Response {
    val builder = chain.request().newBuilder()
    val cookies = cookiesDao.getAll().toBlocking().first()
    builder.addHeader("Cookie", "JWT=" + cookies.jwt)
   
    return chain.proceed(builder.build())
}