CookieManager.getCookie() always returns null (Version <= API 28 (Pie))

2.1k Views Asked by At

I use a standard android.webkit.Webview in a Java-Based native android app. Inside the Webview the User logs into a webapp. After successful login the webapp stores a cookie with the access token. I want to access this cookie.

The cookie has the following characteristics:

  • HTTPS Url Structure like: https://api.example.com
  • httpOnly Flag
  • Secure Flag

When on Android API Level 29 or API Level 30, calling CookieManager.getCookie("https://api.example.com") works like expected and returns a String containing the Value of the Cookie.

When on Android API Level 28 or lower, calling the same method always returns null. Nevertheless calling the CookieManager.hasCookies() returns true and the fact that the webapp in Webview is working as expected shows that the cookie must exist somewhere.

I need to persist the cookie for handling "external" Downloads and other API Calls not executed within the Webview.

Why is this not working below API 28 and how can I solve it?

Things already tried:

  • Calling the method CookieManager.getCookie("https://api.example.com") on different event hooks from WebChromeClient, WebViewClient (e.g. onPageStarted, onPageFinished, onProgressChanged, shouldInterceptRequest, shouldOverrideUrlLoading)
  • Flushing the cookies from memory to persistent storage using CookieManager.flush() in different places.
  • Extracting the cookie by intercepting traffic (this is too hacky using existing hooks)

Assumptions:

  • Threading?, API Support below 28 incomplete?
2

There are 2 best solutions below

0
On

When using older API Versions below 28, the standard WebView Implementation is below 72, or the standard Chrome Webview.

In Version 72 there is a Bug in parsing Cookies with the SameSite Attibute. As a sideeffect, the CookieManager does not hand over Cookies with the Attribute. Therefore a newer Webview Implementation needs to be placed on the device (e.g. via PlayStore Update of Android WebView), otherwise getCookie(url) will always return null.

This affects Emulators with the default Google Images. Therefore a dev may have a hard time finding this. :)

More Info can be found here: https://bugs.chromium.org/p/chromium/issues/detail?id=780491

0
On
Get Cookies with HttpUrlConnection

    String mCookieHeader = "Set-Cookie";
    String mUrl = "https://www.google.co.in/";
    Map<String, List<String>> headerFields = httpConnection.getHeaderFields();
    List<String> cookiesHeaderList = headerFields.get(mCookieHeader);

    CookieManager cookiemanager = CookieManager.getInstance();
    cookiemanager.setAcceptCookie(true);
    cookiemanager.acceptCookie();

    if (cookiesHeaderList != null) {
        for (String cookie : cookiesHeaderList) {
            cookiemanager.setCookie(mUrl, HttpCookie.parse(cookie).get(0).toString());
        }
    }

    Log.e(" cookie ", "" + cookiemanager.getCookie(mUrl));