Cookie is not sent on android 4.1.2 webview - android

I have a method that sets and saves a Session Cookie for Android WebView. This code lets me to send a cookie with request that goes by loading url into webview. Unfortunately its not sent on device with android 4.1.2.
private void handleSessionCookieFromWebView() {
CookieManager cookieManager = CookieManager.getInstance();
if (sessionCookie != null) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP){
cookieManager.removeSessionCookie();
}
else {
cookieManager.removeSessionCookies(null);
}
String cookieString = JSESSION_ID + sessionCookie.getValue();
cookieManager.setCookie(sessionCookie.getDomain(), cookieString);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
CookieSyncManager.createInstance(FunctionActivity.this);
CookieSyncManager.getInstance().sync();
}
else {
cookieManager.flush();
}
}
}
I call it before loading URL into WebView. Any ideas what's the problem? Maybe some kind of workaround?

Related

Android Share cookie with Webview and Volley request

I have searched through a lot of answers and implemented one which helped me with maintaining cookies in volley request.
Code which helped me is following
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
That code has helped me maintain same session with all volley request.
Right after this code I open a webview in onCreate method. Webview has different session and not shared with volley request.
How can I make sure that both has same session.
Following is my onCreate method
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webview);
/* Dialog view */
LinearLayout linearLayoutProgressBar = findViewById(R.id.linearLayoutProgressBar);
// Creates instance of the manager.
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setSaveFormData(true);
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
WebViewClientImpl webViewClient = new WebViewClientImpl(this, linearLayoutProgressBar);
webView.setWebViewClient(webViewClient);
webAppInterface = new WebAppInterface(this, webView);
webView.addJavascriptInterface(webAppInterface, "Android");
webView.loadUrl(AppConstants.mobileUrl);
//GetLocation function fetches the location and sends it to server.
//So first webview is opened and then data is sent to server.
getLocation();
}
Thank you
Another solution is to use CookieManager. The issue is that there are many CoockieManager depending on the context used. With Volley it is java.net.CookieManager and with WebView it is android.webkit.CookieManager. Both are not compatible with each other.
The solution I found here is to create your own CookieManager extended from java.net.CookieManager. The goal is to send the request to the android.webkit.CookieManagerin the same time. Like this, both are synchronized.
Juste create the following class as is :
public class WebkitCookieManagerProxy extends CookieManager
{
private android.webkit.CookieManager webkitCookieManager;
public WebkitCookieManagerProxy()
{
this(null, null);
}
public WebkitCookieManagerProxy(CookieStore store, CookiePolicy cookiePolicy)
{
super(null, cookiePolicy);
this.webkitCookieManager = android.webkit.CookieManager.getInstance();
}
#Override
public void put(URI uri, Map<String, List<String>> responseHeaders) throws IOException
{
// make sure our args are valid
if ((uri == null) || (responseHeaders == null)) return;
// save our url once
String url = uri.toString();
// go over the headers
for (String headerKey : responseHeaders.keySet())
{
// ignore headers which aren't cookie related
if ((headerKey == null) || !(headerKey.equalsIgnoreCase("Set-Cookie2") || headerKey.equalsIgnoreCase("Set-Cookie"))) continue;
// process each of the headers
for (String headerValue : responseHeaders.get(headerKey))
{
this.webkitCookieManager.setCookie(url, headerValue);
}
}
}
#Override
public Map<String, List<String>> get(URI uri, Map<String, List<String>> requestHeaders) throws IOException
{
// make sure our args are valid
if ((uri == null) || (requestHeaders == null)) throw new IllegalArgumentException("Argument is null");
// save our url once
String url = uri.toString();
// prepare our response
Map<String, List<String>> res = new java.util.HashMap<String, List<String>>();
// get the cookie
String cookie = this.webkitCookieManager.getCookie(url);
// return it
if (cookie != null) res.put("Cookie", Arrays.asList(cookie));
return res;
}
#Override
public CookieStore getCookieStore()
{
// we don't want anyone to work with this cookie store directly
throw new UnsupportedOperationException();
}
}
And finally, call once only, early in your code and before any https request :
WebkitCookieManagerProxy coreCookieManager = new WebkitCookieManagerProxy(null, java.net.CookiePolicy.ACCEPT_ALL);
java.net.CookieHandler.setDefault(coreCookieManager);
After looking for a solution for a long time, I found it here: Two way sync for cookies between HttpURLConnection (java.net.CookieManager) and WebView (android.webkit.CookieManager)
From Volley Request, you have to take a cookie and store in shared preference.
then you can set the same cookie with your web view settings.
To retrieve cookie details from volley refer this link
To set the cookie to web view URL like
CookieManager cookieManager = CookieManager.getInstance();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
cookieManager.setAcceptThirdPartyCookies(webView, true);
} else {
cookieManager.setAcceptCookie(true);
}
cookieManager.setCookie(url, ${cookie});
webView.load(url);

How to set cookie in android WebView client

I want to call one specific url via WebView. The page can only be called after user already logged in. I use AsyncHttpClient library to perform login call. Once after successfully logged in , loading url via WebView doesn't seem recognise the proper headers esp cookie. My suspect is that cookies are not sync correctly between HttpClient and WebView's HttpClient . Any idea why ? . Here is how i use WebView
final WebView webView = (WebView) content.findViewById(R.id.web_travel_advisory);
String url = "http://mydomainurl.com/get_data_after_login";
webView.setWebViewClient(new WebViewClient());
CookieSyncManager.createInstance(getActivity());
CookieSyncManager.getInstance().startSync();
CookieManager.getInstance().setAcceptCookie(true);
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl(url);
Appreciate ur help .
Ohh after several hours, i finally figured it out to get it worked. Firstly CookieSyncManager is deprecated on later version of android since api 21 according to doc. So decided not to use it anymore. Secondly CookieManager is used to store cookie for WebView.
Final code
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
List<Cookie> cookies = WSHelper.cookieStore.getCookies();
cookieManager.removeAllCookie();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().contains("session")){
String cookieString = cookie.getName() + "=" + cookie.getValue() + "; Domain=" + cookie.getDomain();
cookieManager.setCookie(cookie.getDomain(), cookieString);
Log.d("CookieUrl",cookieString + " ");
}
}
}
webView.loadUrl(url);
The key changes to solution is: use cookie.getDomain() instead of explicit domain.
cookieManager.setCookie(cookie.getDomain(), cookieString);
Try this code, after few changes works for me:
public class WebViewActivity extends Activity{
private SharedPreferences mPreferences;
String token="";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.webviewpage);
mPreferences = getSharedPreferences("CurrentUser", MODE_PRIVATE);
}
public void LaunchWebView(View view) {
WebView myWebView = (WebView) findViewById(R.id.myWebView);
myWebView.getSettings().setJavaScriptEnabled(true);
myWebView.getSettings().setSaveFormData(false);
CookieSyncManager.createInstance(this);
CookieSyncManager.getInstance().startSync();
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
CookieManager.getInstance().setAcceptThirdPartyCookies(myWebView, true);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
String token2= mPreferences.getString("auth_token","");
HashMap<String, String> map = new HashMap<String, String>();
map.put("x-auth-token", token);
myWebView.getSettings().setAppCacheEnabled(true);
myWebView.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view,String url) {
view.loadUrl(url);
return true;
}
});
myWebView.loadUrl("YOUR_URL", map);
}
}
My problem was slightly different, but answer from #Tixeon gave me the key to solve it. I was composing my Cookie and adding it to the WebView request, but I discovered that Android was overriding my Cookie and sending its own Cookie.
So first of all, I had to remove all cookies from the array, then compose my own Cookie. This is the sample code:
// Note that my project has minSdkVersion 21, so I can directly use methods only available in Lollipop
private fun loadUrlInWebView(url: String) {
webView.settings.apply {
builtInZoomControls = false
javaScriptEnabled = true
useWideViewPort = true
loadWithOverviewMode = true
setSupportMultipleWindows(false)
}
CookieManager.getInstance().apply {
setAcceptThirdPartyCookies(webView, true) // My minSdkVersion is 21
removeAllCookies { value ->
Log.d("Cookies", "Removed all cookies from CookieManager")
}
}
webView.apply {
isVerticalScrollBarEnabled = true
isHorizontalScrollBarEnabled = true
loadUrl(
url,
mutableMapOf(
"Cookie" to "ThisIsMyCookieWithMyValues",
"Accept" to "*/*",
"Accept-Encoding" to "gzip, deflate",
"Cache-Control" to "no-cache",
"Content-type" to "application/x-www-form-urlencoded"
)
)
}
}
Now the request contains my Cookie and not the default one provided by Android, and my session in WebView is working. Hope this helps someone else
Latest way to set cookies using cookieManager
val siteCookies = CookieManager.getInstance().getCookie(“https://www.dummyurl.com”)
cookieManager.removeSessionCookies {
if (! siteCookies.isNullOrEmpty()) {
val cookie = siteCookies.split("; ".toRegex())
.dropLastWhile { it.isEmpty() } as ArrayList<String>
val iterator = cookie.iterator()
while (iterator.hasNext()) {
val cookie = iterator.next()
if (cookie.isNullOrEmpty()) continue
cookieManager.setCookie(“https://www.dummyurl.com”, cookie)
}
}
}
posting this if this helps someone.

WebView.loadUrl(url, headers) not working in android

I am setting the cookie in headers and call WebView.loadUrl() with this header but it(Cookie in header) will not work on any android device except 4.4. I have test it on android versions 4.2, 4.3, 4.4, 5.0 and 5.1.
webView = (WebView) findViewById(R.id.web_view);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setDisplayZoomControls(false);
HashMap <String, String> extraHeaders = new HashMap<String, String>();
extraHeaders.put("Cookie", "{cookie value}");
webView.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url){
view.loadUrl(url, extraHeaders);
return false;
}
});
webView.loadUrl(url, extraHeaders);
Have you tried this
CookieManager.getInstance().setAcceptCookie(true);
if you are using Android Lollipop, then
CookieManager.getInstance().setAcceptCookie(true);
won't work. You need to use
CookieManager.getInstance().setAcceptThirdPartyCookies(true);
To set cookie use the following method
CookieManager.getInstance().setCookie(BuildConfig.BASE_SERVER_ENDPOINT,COOKIE_VAL);
Make sure the base endpoint matches the base url of the links opened in the webview.
To remove cookie
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
CookieManager.getInstance().removeAllCookies(null);
} else {
CookieManager.getInstance().removeAllCookie();
}
This is just a quick post about adding cookies to a web view. If you’ve ever tried to do this the way most people have said that it should be done, you’ve failed miserably and found this post. :)
The way it’s supposed to work is you set the cookie on the CookieManager and then tell the CookieSyncManager to sync.
CookieManager.getInstance().setCookie(domain, value);
CookieSyncManager.getInstance().sync();
I’ve never got this to work as described. With or without async tasks waiting for the threads to catch up.
Instead, I just add the cookie in the header of all the loadUrl calls.
Map<String, String> headers = new HashMap<String, String>();
headers.put("Cookie", "cookieName=cookieValue;domain=domain.com;path=/;Expires=Thu, 2 Aug 2021 20:47:11 UTC;");
webView.loadUrl("myurl.com", headers );
Caveat: I only need to initially load the appropriate cookie for the request, if you want to cover nested calls from inside the browser, you need to override shouldOverrideUrlLoading.
webView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url, headers);
return false;
}
});
If you need to inject the cookie for all requests(including images, js, etc), you’re going to need to override shouldInterceptRequest,
It's beceause of Cookie Policy, to fix it, you should add this :
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
super.init();
// Allow third party cookies for Android Lollipop
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
WebView webView = (WebView)super.appView;
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptThirdPartyCookies(webView,true);
}
super.loadUrl(Config.getStartUrl());
}
I got the solution for the issue by creating the custom cookie manager:
public class WebkitCookieManagerProxy extends CookieManager {
private android.webkit.CookieManager webkitCookieManager;
public WebkitCookieManagerProxy() {
this(null, null);
}
public WebkitCookieManagerProxy(CookieStore store, CookiePolicy cookiePolicy) {
super(null, cookiePolicy);
this.webkitCookieManager = android.webkit.CookieManager.getInstance();
}
#Override
public void put(URI uri, Map<String, List<String>> responseHeaders) throws IOException {
// make sure our args are valid
if ((uri == null) || (responseHeaders == null)) return;
// save our url once
String url = uri.toString();
// go over the headers
for (String headerKey : responseHeaders.keySet()) {
// ignore headers which aren't cookie related
if ((headerKey == null) || !(headerKey.equalsIgnoreCase("Set-Cookie2") || headerKey.equalsIgnoreCase("Set-Cookie"))) continue;
// process each of the headers
for (String headerValue : responseHeaders.get(headerKey)) {
this.webkitCookieManager.setCookie(url, headerValue);
}
}
}
#Override
public Map<String, List<String>> get(URI uri, Map<String, List<String>> requestHeaders) throws IOException {
// make sure our args are valid
if ((uri == null) || (requestHeaders == null)) throw new IllegalArgumentException("Argument is null");
// save our url once
String url = uri.toString();
// prepare our response
Map<String, List<String>> res = new java.util.HashMap<String, List<String>>();
// get the cookie
String cookie = this.webkitCookieManager.getCookie(url);
if (cookie != null) res.put("Cookie", Arrays.asList(cookie));
return res;
}
#Override
public CookieStore getCookieStore() {
// we don't want anyone to work with this cookie store directly
throw new UnsupportedOperationException();
}
}
And initialize the custom cookie manager in Application class or when application starts as:
android.webkit.CookieSyncManager.createInstance(this);
android.webkit.CookieManager.getInstance().setAcceptCookie(true);
WebkitCookieManagerProxy coreCookieManager = new WebkitCookieManagerProxy(null, java.net.CookiePolicy.ACCEPT_ALL);
java.net.CookieHandler.setDefault(coreCookieManager);
If you are using Android Lollipop i.e. SDK 21, then:
CookieManager.getInstance().setAcceptCookie(true);
won't work. You need to use:
CookieManager.getInstance().setAcceptThirdPartyCookies(true);
I ran into same issue and the above line worked as a charm.

Strange Cookie Issue in Android WebView?

I have native application in Andriod and Iphone with ASP.NET as a back-end. I am sending request to my ASP.NET server API by appending Session_Id cookie using HttpClient classes which works great. But I also need to send the same session in WebView. The problem is that some times WebView send the Session_Id cookie and sometimes doesn't. It strange for me. I am not able to find why sometimes webview send the cookie and sometimes doesn't. Here is my code,
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myapp = ((....) getApplicationContext());
setTimeout(true);
try {
getActionBarHelper().setupHomeActivity();
} catch (Exception e) {
e.printStackTrace();
}
cm = (ConnectivityManager) this.getSystemService(Activity.CONNECTIVITY_SERVICE);
webView = new CustomWebView(this, this);
webView.getWebView().addJavascriptInterface(new MyJavaScriptInterface(), "android");
getTimeDiff();
if(MyApplication.INSTANCE.isLoggedin()){
Cookie sessionCookie = MyApplication.INSTANCE.getCookie();
List<Cookie> cookies = MyApplication.INSTANCE.getClient().getCookieStore().getCookies();
for (int i = 0; i < cookies.size(); i++) {
sessionCookie = cookies.get(i);
}
try{
if(sessionCookie!=null){
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
if (sessionCookie != null) {
cookieManager.removeSessionCookie();
String cookieString = sessionCookie.getName() + "="
+ sessionCookie.getValue() + "; domain="
+ sessionCookie.getDomain();
if (MyApplication.isDebug())
cookieManager.setCookie(sessionCookie.getDomain(),(sessionCookie.getName() + "=" + sessionCookie.getValue()));
CookieSyncManager.getInstance().sync();
}else{
if (MyApplication.isDebug())
Log.d("WebView", " Cookie is null: " );
}
}else{
if (MyApplication.isDebug())
Log.d("WebView", " Cookie is null: " );
}
}catch (Exception e) {
e.printStackTrace();
}
Log.e("WenView", "============================ ");
}
}
Your for loop appears to only include the single line that retrieves the cookie... so your logic that's setting the cookie below only gets called once, with whatever the last cookie happened to be. Since the cookies aren't ordered in the list, this probably explains why sometimes it works and sometimes it doesn't; it's working when your cookie is last, and failing otherwise.
The answer is to just expand your for loop to include ALL the logic underneath as well. Your copying code looks fine, and I expect it is if you can get it to work sometimes.

Android WebView not extracting all cookies on different devices

I'm trying to extract the value of a cookie from a webpage after logging in. I am using a cookie helper class and the android.webkit.CookieManager to retreive cookies once the webpage has finished loading i.e. onPageFinished()
This all works fine and I can see the cookie names and values on my test devices, Galaxy S2 (4.0.4), Galaxy S3 (4.1.1) and a HTC Explorer (2.3). However, the same code is not functioning on a Sony Xperia (2.3)?
I have logged out the url to make sure I'm working from the correct page and for some reason I only get 3 cookies from the site on the Xperia, where I should be getting 7 (roughly).
Below is a simplified version of the code I'm running. Appreciate any responses. Thanks in advance!
WebViewActivity
#Override
public void onPageFinished(WebView view, String url) {
if(!cookieCreated){
CookieHelper cookieHelper = new CookieHelper(getApplicationContext());
if(cookieHelper.processCookie(url)){
cookieCreated = true;
}
}
}
CookieHelper
public CookieHelper(Context cont){
this.cookieManager = CookieManager.getInstance();
}
public void processCookie(String url){
if(manager.getCookie(url).contains("cookie_name_required")){
Log.d(TAG, "Got cookie");
}
else{
Log.d(TAG, "No cookie");
}
}
public static void setCookies(Context context) {
//gets all cookies from the HttpClient's cookie jar
List<Cookie> cookies = httpClient.getCookieStore().getCookies();
if (! cookies.isEmpty()) {
CookieSyncManager.createInstance(context);
CookieManager cookieManager = CookieManager.getInstance();
//sync all the cookies in the httpclient with the webview by generating cookie string
for (Cookie cookie : cookies) {
Cookie sessionInfo = cookie;
String cookieString = sessionInfo.getName() + "=" + sessionInfo.getValue() + "; domain=" + sessionInfo.getDomain();
cookieManager.setCookie("zoboon.com", cookieString);
CookieSyncManager.getInstance().sync();
}
} else {
Log.i("httpclient","has no cookies");
}
}

Categories

Resources