How to implement cookie handling on Android using OkHttp?

AndroidCookiesOkhttp

Android Problem Overview


Using OkHttp by Square <https://github.com/square/okhttp>;, how can I:

  1. Retrieve a cookie returned from the server
  2. Store the cookie for upcoming requests
  3. Use the stored cookie in subsequent requests
  4. Update the cookie returned by the subsequent request

Ideally the cookie would be stored, resent and updated automatically with every request.

Android Solutions


Solution 1 - Android

For OkHttp3, a simple accept-all, non-persistent CookieJar implementation can be as follows:

OkHttpClient client = new OkHttpClient.Builder()
    .cookieJar(new CookieJar() {
        private final HashMap<HttpUrl, List<Cookie>> cookieStore = new HashMap<>();

        @Override
        public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
            cookieStore.put(url, cookies);
        }

        @Override
        public List<Cookie> loadForRequest(HttpUrl url) {
            List<Cookie> cookies = cookieStore.get(url);
            return cookies != null ? cookies : new ArrayList<Cookie>();
        }
    })
    .build();

Or if you prefer to use java.net.CookieManager, include okhttp-urlconnection in your project, which contains JavaNetCookieJar, a wrapper class that delegates to java.net.CookieHandler:

dependencies {
    compile "com.squareup.okhttp3:okhttp:3.0.0"
    compile "com.squareup.okhttp3:okhttp-urlconnection:3.0.0"
}

CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
OkHttpClient client = new OkHttpClient.Builder()
    .cookieJar(new JavaNetCookieJar(cookieManager))
    .build();

Solution 2 - Android

For OkHttp 3 (or maybe newer)

See hidro's answer

For OkHttp 2.x (or maybe older)

You can pass a CookieHandler to your OkHttpClient instance. You can use the CookieManager implementation from java.net or you could implement your own if you want. Choose the policy that works best for your needs.

OkHttpClient client = new OkHttpClient();
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
client.setCookieHandler(cookieManager);

OkHttp will save cookies received from Responses into the CookieHandler and read from it when sending requests. It will do so for matching request/response URIs.

Solution 3 - Android

I needed to share the default Cookie Jar (CookieManager.getInstance()) so this seemed to work ok for me.

return new CookieJar() {

        @Override
        public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
            CookieManager cookieManager = CookieManager.getInstance();

            for (Cookie cookie : cookies) {
                cookieManager.setCookie(url.toString(), cookie.toString());
            }
        }

        @Override
        public List<Cookie> loadForRequest(HttpUrl url) {
            CookieManager cookieManager = CookieManager.getInstance();
            List<Cookie> cookies = new ArrayList<>();
            if (cookieManager.getCookie(url.toString()) != null) {
                String[] splitCookies = cookieManager.getCookie(url.toString()).split("[,;]");
                for (int i=0; i<splitCookies.length; i++) {
                    cookies.add(Cookie.parse(url, splitCookies[i].trim()));
                }
            }
            return cookies;
        }
    };

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDanielView Question on Stackoverflow
Solution 1 - AndroidhidroView Answer on Stackoverflow
Solution 2 - AndroidMiguelView Answer on Stackoverflow
Solution 3 - AndroidhmacView Answer on Stackoverflow