Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CookieManager.getInstance().removeAllCookie(); doesn't remove all cookies

I call CookieManager.getInstance().removeAllCookie() in onCreate in my app.

I'm running into a weird issue where I'm seeing an unexpected cookie value get passed up in a GET request. In fact, the cookie value is a really, really old value.

Here are the steps I perform for the test:

  1. Install the app
  2. Make a GET request on app launch. Request should be clean: no cookies should be sent up.
  3. GET request responds with a Set-Cookie. The value is based on the request time, so there's a very small chance this value is the same on any two requests.
  4. Make another GET request. Request should send up cookie value from step 3.

The first time I installed the app, the cookie behavior worked as I expected above. I uninstalled the app, then re-installed it, and the cookie behavior, again, worked as expected. I do this a few times, things are fine and dandy.

Then, suddenly, on the Nth install, step 2 doesn't pass. The very first GET request isn't clean. In fact, it's comes in with a value that was set on the first install of the app.

I can't reproduce this problem reliably, but I do see it quite often. It's not that the first GET request on install is sending up a cookie value from the immediately previous install -- the value is from three or four previous installs which were all followed by uninstalls.

How is it possible that I'm seeing this? How can I actually remove all of the app's cookies?

like image 999
user5243421 Avatar asked Dec 15 '12 23:12

user5243421


3 Answers

Please call CookieSyncManager.getInstance().sync() immediately after CookieManager.getInstance().removeAllCookie() call.

The reason is as mentioned by @mgibsonbr, a separate thread saves the cookies between, driven by a timer so to make it persistent immediately call CookieSyncManager.getInstance().sync() explicitly.

like image 43
Rajaraman Subramanian Avatar answered Oct 15 '22 10:10

Rajaraman Subramanian


This is a shot in the dark, but maybe the cookies from your first install are in persistent storage, while the ones from reinstalls are cached in the RAM. Maybe the action of removing all cookies is not being sync'ed to persistent storage for some reason, so it keeps the old values around between reinstalls.

Quoting the docs for CookieSyncManager (emphasis mine):

The CookieSyncManager is used to synchronize the browser cookie store between RAM and permanent storage. To get the best performance, browser cookies are saved in RAM. A separate thread saves the cookies between, driven by a timer.

...

The sync interval is 5 minutes, so you will want to force syncs manually anyway, for instance in onPageFinished(WebView, String). Note that even sync() happens asynchronously, so don't do it just as your activity is shutting down.

That strongly suggests that maybe (on your tests, which I assume were sometimes made in intervals of less than 5 minutes) when the app was uninstalled it hadn't sync'ed yet, so the old values from the first install were still in the persistent storage at this point. I have also no reason to assume that sync would happen during an uninstall if the 5 minutes interval hadn't passed.

That leaves one question: why sometimes some cookies are sent even though you cleared them in onCreate? It turns out the removeAllCookie is also asynchronous - sometimes it will have completed before you make your first request, sometimes it will not, and in the latter case it will send the values that are still active: the ones from your first install, that are still in persistent storage.

(Please note that I'm still learning Android development, and some of my assumptions might be wrong - about how cookies are managed and about whether or not an asynchronous call made in one state in the activity's lifecycle might still be unfinished when another one runs; but this interpretation is pretty consistent with the behavior you're describing)

like image 107
mgibsonbr Avatar answered Oct 15 '22 08:10

mgibsonbr


if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
        CookieManager.getInstance().removeAllCookies(null);
    } else {

        CookieSyncManager.createInstance(context);
        CookieManager cookieManager = CookieManager.getInstance();
        if (cookieManager != null) {
            cookieManager.removeAllCookie();
        }
 CookieSyncManager.getInstance().sync();
}
like image 33
Y.yue Avatar answered Oct 15 '22 10:10

Y.yue