Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OkHttp CookieJar fails to add cookie to request

I'm trying to add a saved authentication cookie to further requests by utilizing a CookieJar. And while getting a correct authentication cookie and saving it to the jar is working great, when inspecting the response.request().headers(), the cookie is nowhere to be found.

I found this especially strange since I found out by debugging that loadForRequest() is called for the request and returns that correct cookie. When using that exact same cookie in Postman to fake the request, it returns the desired result (a page without a login form).

Could someone try to explain what I'm missing?

Class where the jar is utilized

class HTMLRoutes {
    var scheme = "https"
    var host = "www.mangaupdates.com"
    val cookieJar = MULoginCookieJar()
    var client = OkHttpClient.Builder()
            .cookieJar(cookieJar)
            .build()
/*Other code*/

private fun getHTMLFromUrl(url: HttpUrl): String {
        var request = Request.Builder()
                .url(url)
                .build()
        client.newCall(request).execute().use { response ->
        //Right before returning response the loadForRequest() method gets called in the MUCookieJar class
            if (response.isSuccessful) {
            //response.request.headers = ""
                if (response.body() != null) {
                    return response.body()!!.string()
                } else {
                    throw IOException("Response body is empty")
                }
            } else {
                throw IOException("Unexpected code" + response)
            }
        }
    }
}

My cookiejar

class MULoginCookieJar : CookieJar {
    private var secureSessionCookie: Cookie? = null

    override fun saveFromResponse(url: HttpUrl?, cookies: MutableList<Cookie>?) {
        if (url != null && cookies != null) {
            if (url.pathSegments().size > 0 && url.pathSegments()[0] == "login.html") {
                for (cookie in cookies) {
                    if(cookie.name() == "secure_session") {
                        secureSessionCookie = cookie
                    }
                }
            }
        }
    }

    override fun loadForRequest(url: HttpUrl?): List<Cookie>? { // url = https://www.mangaupdates.com/series.html?id=14829
        if(url != null && url.pathSegments().size > 0 && url.pathSegments()[0] == "login.html") {
            return emptyList()
        }

        val cookies: List<Cookie> = if(secureSessionCookie==null) emptyList() else listOf(secureSessionCookie!!)
        return cookies // = ["secure_session=601bbc74; expires=Sun, 07 Oct 2018 20:45:24 GMT; domain=www.mangaupdates.com; path=/; secure; httponly"]
    }
}

Help is immensely appreciated. I have been a long time lurker but this is the first time I have been this stumped at a problem.

like image 605
Anthony Baert Avatar asked Oct 12 '17 20:10

Anthony Baert


1 Answers

I would recommend using an existing cookie jar instead of creating your own. The rules around cookies can get a bit complex.

import okhttp3.JavaNetCookieJar;

CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
JavaNetCookieJar cookieJar = new JavaNetCookieJar(cookieManager);

OkHttpClient client = new OkHttpClient.Builder().cookieJar(cookieJar).build();

Also to help debug you can set up OkHttp debug logging with an interceptor.

Logger logger = LoggerFactory.getLogger(HttpUtil.class);
HttpLoggingInterceptor logging =
    new HttpLoggingInterceptor((msg) -> {
        logger.debug(msg);
    });
logging.setLevel(Level.BODY);

client.addNetworkInterceptor(logging);
like image 138
Bill O'Neil Avatar answered Oct 27 '22 07:10

Bill O'Neil