How to implement cookie handling on Android using OkHttp?
AndroidCookiesOkhttpAndroid Problem Overview
Using OkHttp by Square <https://github.com/square/okhttp>;, how can I:
- Retrieve a cookie returned from the server
- Store the cookie for upcoming requests
- Use the stored cookie in subsequent requests
- 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;
}
};