A tale on Android cookies store management
Cookies storing is an essential part of Android development, used extensively in authentication. Here I’m sharing various options of managing cookies store in Android using a tale as below.
Along with it, I also provide sample Apps (with codes) for all of the scenarios below.
In the beginning
An APP was created. A well polished app that performs its function well. But it is just interacting by itself. No one else to talk to. Self sufficient.
One day, it gets connected to Mr. API. Mr. API would want to give it some cookies.
However, the APP doesn’t have anything to store the cookies. Hence every time it restarts itself, the cookies are cleared, as show in my example App below (below I actually use a hashmap to store it, just to show the data temporary)
Learning to save
Mr. API is not happy that APP is not storing the given cookies, as that defeats the purpose of APP having the cookies.
Hence the APP now has to do something to store the cookies, so that it doesn’t loose it every time it restarts.
However the APP doesn’t want to build itself the storage. Fortunately a library was found that help with that i.e. PersistentCookieJar.
This was good, as APP doesn’t need to always rely on Mr. API anymore for the previous cookies it obtained even after it restart itself.
A new relationship
One day, the APP discover it needs to talk to a new person, Ms. Webview. Ms. Webview wanted the cookies that APP received from Mr. API in order to recognize APP is trustable.
Unfortunately, with what’s available, APP is not able to share its cookies with Ms Webview. This is illustrated in my example App below (i.e. it can store the cookie, but not send over to Webview)
Learning to give in a right way
In order to be connected to Ms. Webview properly, APP has to share cookies with Ms. Webview in the way she prefers, that is through the WebKit CookieManager.
The plan is, every time APP plan to launch Webview, the cookies will need to be copied from the PersistentCookieJar to the CookieManager.
Hurray! APP can now be trusted by Ms. Webview, and she will perform what she is meant to do.
A new desire… bidirectional relationship
This all works fine. But APP feels something is still missing.
APP constantly gives cookies to Ms. Webview. However, whenever Ms. Webview has changes the cookies or has a new cookie, APP is totally unaware of it. It’s a one way relationship.
This is illustrated by my example App below (i.e. it can store the cookie, and send it over to Webview. But if Webview changes the cookie, APP will not get the change)
Learning to share
APP then have an idea, “Why not we just share one approach of Cookie Storing, instead of two?”
We know Ms. Webview will only like her way of getting cookies, that’s Webkit CookieManager. So, APP decided to not use PersistentCookieStore, but just share Webkit CookieManager with Ms. Webview.
This is illustrated as below.
How to do it? Apparently there are several ways of doing it as shared below
Illustrated in my App Example as below (i.e. it can store the cookie, and send it over to Webview, and get webview changed cookies as well)
And with this, they live happily ever after … (or maybe not, if they start to mess around each other cookies in a way not intended by the other party :P)
Hopes you like the story above that links you to 4 different App cookies storing above
- No storing or just using Hashmap — non persistent, every time restart, all cookies need to be retrieved again
- Using PersistentCookieJar — persistent and good for encapsulating the Cookies within the App itself, without sharing with any Webview
- Using PersistentCookieJar by sync to CookieManager — Need for the case where Webview need the token from App to authenticate. But App would like to have it’s own cookie secured not changed by Webview
- Sharing CookieMnager — Useful for the case where there’s tight coupling of App and Webview interaction (e.g. reissue of token could happen either side, and both would benefit from it).
The example APP is stored in the below structure, each is an App by itself, and shared the same base-module.