Lets prepare for cookie storing:
CookieSyncManager.createInstance(getApplicationContext());
CookieSyncManager.getInstance().startSync();
CookieManager.getInstance().setAcceptCookie(true);
Then I'm putting manually some cookies, lets say PHPSESSID and RANDOM
CookieManager.getInstance().setCookie("domain.com", "PHPSESSID="+phpSession);
CookieManager.getInstance().setCookie("domain.com", "RANDOM="+random);
lets check is it working using:
CookieManager.getInstance().getCookie("domain.com");
and got
PHPSESSID=dba4ff392agd39b5951d10a91a0a7b56; RANDOM=266284790:1466147978:c91d0896bac59e0b
Everything looks good, but when I navigate in may app to one of WebView Activities, which are opening same domain website also setting cookies, then when I print cookie like above it looks like this:
PHPSESSID=dba4ff392agd39b5951d10a91a0a7b56;
RANDOM=266284790:1466147978:c91d0896bac59e0b;
PHPSESSID=9ecb5156cf8fc3190fbc69fd13393243;
RANDOM=265078219%3A1463147975%3Ad0448d163e9b2123
duplicated entries... when after that I manually set again e.g. RANDOM with setCookie:
PHPSESSID=dba4ff392agd39b5951d10a91a0a7b56;
RANDOM=111111111:2222222222:33333336bac59e0b;
PHPSESSID=9ecb5156cf8fc3190fbc69fd13393243;
RANDOM=265078219%3A1463147975%3Ad0448d163e9b2123
values set by WebView are not overwritten, only my "manually" entered... how to force WebView to use my earlier set cookie OR overwrite already set?
As in the MDN docs about Set-Cookie you can see many different kinds of cookie values, a cookie can be set to particular Path
cookie-name=cookie-value; Path=path-value
And in CookieManager.setCookie void setCookie (String url, String value), the android reference says:
Sets a cookie for the given URL. Any existing cookie with the same host, path and name will be replaced with the new cookie. The cookie being set will be ignored if it is expired.
In my opinion, the reason that you have duplicate entries is because the cookie values were in different Path. So if you want to overwrite you should make sure host path name are the same.
private void setCookieManager(String auth_token) {
CookieSyncManager manager = CookieSyncManager.createInstance(this);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
cookieManager.removeSessionCookie();
cookieManager.setCookie(auth_token);
manager.sync();
}
I think you just didn't setup your cookie manager properly. Give this a try
Related
I am using Android Web View in my Xamarin Project to perform third party authentication. Once the login is successful I need to extract the authentication cookies. This cookies I am storing in persistent storage and then I am using them for passing to subsequent requests.
For example:
Android App >(opens) webview > Loads (idp provider) url > User provides credentials and saml request is sent to my backend server > backend server validates saml and returns authentication cookies.
It returns two cookies.
Now everything works fine. And in OnPageFinished method of the WebClient of webview I am trying to extract the cookies using the method.
public override void OnPageFinished(WebView view, string url)
{
base.OnPageFinished(view, url);
var handler = OnPageCompleted;
var uri = new Uri(url);
AllowCookies(view);
var cookies = CookieManager.Instance.GetCookie(url);
var onPageCompletedEventArgs = new OnPageCompletedEventArgs { Cookies = cookies, Url = uri.AbsolutePath, RelativeUrl = uri.PathAndQuery, Host = uri.Host };
handler?.Invoke(this, onPageCompletedEventArgs);
}
private void AllowCookies(WebView view)
{
CookieManager.Instance.Flush();
CookieManager.AllowFileSchemeCookies();
CookieManager.SetAcceptFileSchemeCookies(true);
CookieManager.Instance.AcceptCookie();
CookieManager.Instance.AcceptThirdPartyCookies(view);
CookieManager.Instance.SetAcceptCookie(true);
CookieManager.Instance.SetAcceptThirdPartyCookies(view, true);
}
The problem is, I am able to get just one cookie(wc_cookie_ps_ck
), I am unable to see the other authentication cookie(.AspNetCore.Cookies
).
Here's how the cookies appear in browser.
Please note that in postman and in chrome browser both the cookies appear.
But in android webview only cookie with name ".AspNetCore.Cookies" is not appearing at all.
As per Java document,"When retrieving cookies from the cookie store, CookieManager also enforces the path-match rule from section 3.3.4 of RFC 2965 . So, a cookie must also have its “path” attribute set so that the path-match rule can be applied before the cookie is retrieved from the cookie store."
Since both of my cookies have different path, is that the reason the one with path set as "/project" is not appearing?
After days and days of finding the answer to the question. I finally have found an answer.
I did remote debugging of the webview with the desktop chrome and I found out that all the cookies that I needed were present in the webview.
However the method,
var cookies = CookieManager.Instance.GetCookie(url);
doesn't return the cookie which has the same site variable set.
This looks like a bug from Xamarin Android. I have already raised an issue in Xamarin Android github.
In the xamarin android github issue I have mentioned the steps to reproduce.
For me, the workaround to resolve the issue was to set the samesite cookie varibale off in my asp.net core back end project.
As follows:
In order to configure the application cookie when using Identity, you can use the ConfigureApplicationCookie method inside your Startup’s ConfigureServices:
// add identity
services.AddIdentity<ApplicationUser, IdentityRole>();
// configure the application cookie
services.ConfigureApplicationCookie(options =>
{
options.Cookie.SameSite = SameSiteMode.None;
});
Link for the above solution mentioned. Here.
i have cookies,want to send the cookie to WebView,how i can do?
i use JSOUP to get cookies from login page and i use the follow code but not working
webview.LoadUrl(URL, Cookies)
I had to do something like this a couple of weeks ago. I ditched the webview though and used a recyclerview for the info because of data and ram consumption.
res = Jsoup.connect(url)
.data("user", user, "passwrd", pass)
.method(Connection.Method.POST)
.execute();
String sessionId = res.cookie("PHPSESSID");
The code up there is actually from Jsoup's creator himself on how to store cookies. Then its a matter of setting the cookiemanager to these cookies.
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
cookieManager.setCookie(url,String.format("%s=%s",
"PHPSESSID", sessionId));
Then I just loaded the webview. I think a really important line here is formatting the string in the second parameter of the setCookie() method to match how the cookie is actually a Map with a key and value of PHPSESSID and the cookies characters. PHPSESSID is the id name that shows up for me in the cookie.
first of all, can someone please explain how does CookieManager.getInstance() work? I don't really get how I can get the session from webview? Lets say if I have this
CookieSyncManager.createInstance(WebviewPage.this);
CookieManager cookieManager = CookieManager.getInstance();
Do I get the session from the class named WebviewPage? but what if I named my actual WebView to webview, how can cookieManager get the session of webview? not even talk about if I had two WebView, webview1 and webview2. How do I know which session that was stored in cookieManager??
My main question is...I have two activities and one webview in each activity. How can I get the session from Activity A and pass it to the webview in Activity B?
Thanks!!!
As far as I know, you don't need to set cookie for webview2.
webview2 will automatically use the cookies from webview1.
CookieManager seems to be a singleton, so when you call getInstance() you always get the same instance. So if webview 1 set some cookies on the CookieManager, or if you set it your self using set Cookie, all other webviews should get the same cookies as well.
I'm trying to set some cookies on my WebView to open a browser with the same session that I have on my app.
I read a lot of answers but they don't work for me. The only solution I've found is in the loadUrl, hardcode the cookie data in extraHeaders, but as expected this only works for this requests, and doesn't maintain the session.
The code that I have is:
CookieSyncManager cookieSyncManager = CookieSyncManager.createInstance(mWebView.getContext());
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
cookieManager.removeSessionCookie();
cookieManager.setCookie("http://xx.xxx.example.com","mid="+MySession.GetSession().sessionId+" ; Domain=.example.com");
cookieSyncManager.sync();
String cookie = cookieManager.getCookie("http://xx.xxx.example.com");
Log.d(LOGTAG, "cookie ------>"+cookie);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebViewClient(new TuWebViewClient());
mWebView.loadUrl("http://xx.xx.example.com");
getCookie() returns the correct data, but when I read the cookies from the server, those are empty. What is wrong? Please advise.
Thank you!!!
Solved!!!! the problem is with the webView, I dont know what happend, but If I create the
WebView webView = new WebView(Activity.this);
it works. If I read the webview from activity with findViewById() it doesn't work.
Also if you need to set a list of cookies that you received previously from a website.
All you have to do is use a for-loop to go through and set all of them . It helped me to solve the situation
CookieSyncManager cookieSyncManager = CookieSyncManager.createInstance(mWebView.getContext());
...
cookieSyncManager.sync();
is the cause of problem. You should do like this:
CookieSyncManager.createInstance(mWebView.getContext());
...
CookieSyncManager.getInstance().sync();
And there will be no need to manually create WebView...
I have trouble passing the cookie into the WebView inject. I know how to inject the cookie. When the cookie is injected I want to display a member.php and this page requires a cookie. It shows me the error page even if I've injected the cookie.
The WebView are correctly loaded and I've tried to set a cookie using the CookieManager class. Alll this is known to me.
From the CookieStore I have tried to print out the whole cookie itself; which prints this:
[[version: 0][name:SQMSESSID][value: 9166729532c975f261bda9e6e583bdba]
[domain: mydomain.com][path: /][expiry: null], [version: 0][name: key]
[value: vrckNRab][domain: mydomain.com][path: /][expiry: null]]
Should be mentioned that the code above is the successful CookieStore when I have passed my correct username and password.
My inject + loadUrl code:
CookieStore cookie = /* CookieStore cookie takes a CookieStore from my
own function that succesful returns the CookieStore */
List<Cookie> listcookie = cookie.getCookies(); //Set my CookieStore to a list
Cookie setcookieOne = listcookie.get(0) //My cookie has two fields
Cookie setcookieTwo = listcookie.get(1) //....and assign these to a cookie
CookieManager cookieManager = CookieManager.getInstance();
CookieSyncManager.createInstance(getApplicationContext());
cookieManager.setAcceptCookie(true);
cookieManager.setCookie(setcookieOne.getDomain(), setcookieOne.getValue());
cookieManager.setCookie(setcookieTwo.getDomain(), setcookieTwo.getValue());
CookieSyncManager.getInstance().sync();
browse.setWebViewClient(new WebViewClient(){
});
browse.loadUrl("http://mypagethatwillredirectmeonacorrectcookie.php"); /* This
page will redirect if the cookie is successful */
Any ideas why it doesn't show the member.php?
First, make sure that getValue() on a Cookie returns what setCookie() on a CookieManager requires. CookieManager needs "The value for set-cookie: in http response header"; Cookie's getValue() I suspect returns only the actual value (9166729532c975f261bda9e6e583bdba in your example).
Second, never use getApplicationContext(), particularly for GUI operations. Use your Activity instead, since Activity is a subclass of Context.