Wednesday, November 23, 2016

Storing Cookies on Android with OkHttp

Not those kinds of cookies... Unfortunately.
Coming from an iOS background, I like how Apple makes things that “just work”. One of the things they got right was the Foundation framework’s URLSession class. Sure there are iOS networking libraries that can do a lot more, but the built in networking handles a lot of the behind the scenes magic for you.

Which is why I was surprised to find that my favorite Android networking library, OkHttp, didn’t have any cookie handling by default. I actually just took this feature for granted. If Apple can do it, then surely the more technical folks can too?

Well after a grueling day of thinking, Googling, and frustration, I got it to work. And it’s not as hard as it seemed. The difficult part is just figuring out how to set it up.

The key is the CookieJar class. In order for it to work, you’ll need to attach it to your OkHttpClient instance before making any calls. First add it to build.gradle

compile 'com.github.franmontiel:PersistentCookieJar:v1.0.0'

Using it in the code would look something like this.


In my case, I had multiple AsyncTasks, so I chose to use the same client for both, hence the client and cookie jar are global. However, because the cookie jar uses shared preferences, this isn’t entirely necessary. The cookies are stored and retrieved from the same place, so in theory, you could create multiple instances of PersistentCookieJar, which is great if you need to access the same site from multiple activities or fragments.

You can now proceed to make the requests as normal, knowing your cookies will be persisted.

There’s just one other thing to ensure everything works properly; you still need to clear cookies manually. This is common when authenticating users. In my case, if the user types their password incorrectly before successfully logging in, the cookies are not properly saved and the server doesn’t realize they’re signed in. Some of the StackOverflow answers out there declare the type as CookieJar, but be sure to use PersistentCookieJar. That way you can clear cookies when you need to, for example, when the user attempts a new login.

mCookieJar.clear();

And there you have it. A little tricky to figure out, but quite simple and powerful. And all the hard work is done for you, just as we like it.