I'm trying to do some post request to a webpage containing json data... but there are cookies involved.
cookies are working fine but aren't persistent....
I'm doing the request from a separate class(object). I pass the activity context to that class but I'm still not able to store the cookies.
I tried using cookiessyncmanager to sync the cookies but this requires a cookiemanger. and that's where I'm stuck because the cookiemanager doesn't allow me to create a context like the cookiesyncmanager does...
here's my code:
for(Cookie cookie : cookieStore.getCookies()){
String cookieString = cookie.getName() + "="
+ cookie.getValue() + "; domain=" + cookie.getDomain();
CookieManager.getInstance().setCookie(cookie.getDomain(),
cookieString);
}
CookieSyncManager.createInstance(baseContext).sync();
as you can see CookieManager allow allows the getInstance() method, but this just results in "failure" as the object obviously doesn't have a context....
Related
I have some http requests. One of them retrieves and parse cookie from it's response. I save this cookie via CookieSyncManager and CookieManager with following code:
CookieSyncManager.createInstance(context);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.removeSessionCookie();
cookieManager.removeAllCookie();
String cookieString = cookie.getName() + "=" + cookie.getValue();
Log.e(getClass().toString(), cookieString);
cookieManager.setCookie(START_PAYMENT_URL, cookieString);
CookieSyncManager.getInstance().sync();
Log.e(getClass().toString(), "Get cookie: " + cookieManager.getCookie(START_PAYMENT_URL));
Both Log.e calls write same cookie. So everything looks ok.
I have different activity which contains WebView. I need to call postUrl(String url) method with some POST params and with authorization cookie. I thought that cookie is in CookieManager and everything should work great. Well. It is. But on 4.x devices only.
On 2.x devices WebView makes postUrl without cookie.
Here is activity code which contains WebView:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.payment_webview);
final String billId = getIntent().getStringExtra(INTENT_BILL_ID);
final WebView webView = (WebView) findViewById(R.id.payment_webview);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Log.e(getClass().toString(), url);
view.loadUrl(url);
return false;
}
});
String postData = "id_bill=" + billId;
Log.d(TAG, "Requesting payment URL " + START_PAYMENT_URL + " with post data: " + postData);
Log.d(TAG, CookieManager.getInstance().getCookie(START_PAYMENT_URL));
webView.postUrl(START_PAYMENT_URL, EncodingUtils.getBytes(postData, "BASE64"));
}
CookieManager.getInstance().getCookie(START_PAYMENT_URL) returns null on 2.x devices and cookie value on 4.x devices.
How to fix this problem?
Seems like I figured out what's the problem.
I just removed
cookieManager.removeSessionCookie();
cookieManager.removeAllCookie();
while I'm saving cookies.
I suppose that problem is that all methods of CookieManager work asynchronously. Probably remove cookies methods invoked after cookieManager.setCookie(START_PAYMENT_URL, cookieString); even if they called before it. So CookieManager saves cookies and after that remove cookies methods invoked.
I know this question has been asked a hundred times, and I've read and tried for 2 hours now, but I can't find my error :-(
I am trying to create a simple webbrowser and therefore have a webview, where I login on a site and get access to a picture area. With help of a DefaultHttpClient, I want to make it possible to download pictures in the secured area.
Therefore I am trying to share the cookies from the webview and pass them on to the HttpClient, so that it is authenticated and able to download. But whatever I try and do, I always get a 403 response back...
Basically the steps are the following:
1) Enter URL, webview loads website
2) Enter login details in a form
3) Navigate to picture and long hold for context menu
4) Retrieve the image URL and pass it on to AsynTask for downloading
Here's the code of the AsyncTask with the Cookie stuff:
protected String doInBackground(String... params) {
//params[0] is the URL of the image
try
{
CookieManager cookieManager = CookieManager.getInstance();
String c = cookieManager.getCookie(new URL(params[0]).getHost());
BasicCookieStore cookieStore = new BasicCookieStore();
BasicHttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
String[] cookieParts = null;
String cookies[] = null;
cookies = c.split(";");
for(int i=0;i<cookies.length;i++)
{
cookieParts = cookies[i].split("=");
BasicClientCookie sessionCookie = new BasicClientCookie(cookieParts[0].trim(), cookieParts[1].trim());
sessionCookie.setDomain(new URL(params[0]).getHost());
cookieStore.addCookie(sessionCookie);
}
DefaultHttpClient httpClient = new DefaultHttpClient();
httpClient.setCookieStore(cookieStore);
HttpGet pageGet = new HttpGet(new URL(params[0]).toURI());
HttpResponse response = httpClient.execute(pageGet, localContext);
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
--> NEVER Happens, always get 403
.) One of the problems is that the webview saves some cookies for the host *www.*example.com, but the image-URL to download (params[0]) is *static.*example.com. The line
cookieManager.getCookie(new URL(params[0]).getHost());
returns null, because there is no cookie for static.example.com, but only for www.example.com.
.) When I manually say cookieManager.getCookie("www.example.com"); I get some cookies back, which I add to the HttpClient cookie store:
There are 5 cookies added
- testcookie = 0
- PHPSESSID = 320947238someGibberishSessionId
- email = my#email.net
- pass = 32423te32someEncodedPassGibberish
- user = 345542
So although these cookies, a session ID and other stuff, get added to the HttpClient, it never get's through to download an image. Im totally lost... though I guess that it either has something to do with the cookies domains, or that Im still missing other cookies.
But from where the heck should I know which cookies exist in the webview, when I have to specify a specific URL to get a cookie back?? :-(
Any advice?
I guess we have made it too complicated in above snippet.
Use these easy steps -
1)Retrieve the cookie from webView -wherever your webview is, use this code to re
String cookie = CookieManager.getInstance().getCookie(
url.toString());
Log.d("mytcs", "cookie downloadlistner " + cookie);
2) Pass this in your downloading asyncTask using params -
downloadImageTask = new DownloadImage();
downloadPDFTask.execute(url, cookie);
(I assume you know to retrieve this cookie in asyncTask, you will use params[1],
3) set this cookie in your http request using -
if (cookie != null)
con.setRequestProperty("cookie", cookie);
where con is HttpURLConnection con;
so you can set it to your need, in HttpGet.
You probably figured out the answer already coz it is a pretty late answer. But, just in case...
Try this. When you retrieve the cookie from WebView just use example.com in the domain name. When you set the cookie in BasicClientCookie and set the domain, set the domain name to .example.com. Note the "." in the beginning. Now, i think the session should work across all subdomains in your application.
in my application, I'm getting two cookies from an HttpGet request and store them in the CookieManager like this:
//Clear old cookies
CookieManager.getInstance().removeAllCookie();
CookieSyncManager.getInstance().sync();
//Save the two cookies: auth token and session info
List<Cookie> cookies = httpclient.getCookieStore().getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
String cookieString = cookie.getName() + "=" + cookie.getValue() + "; Domain=" + cookie.getDomain();
CookieManager.getInstance().setCookie("http://alpha.mydomainname.com", cookieString);
}
System.out.println(CookieManager.getInstance().hasCookies()); //Prints false in 2.3, true in 4.0.3
CookieSyncManager.getInstance().sync();
System.out.println(CookieManager.getInstance().hasCookies()); //Also prints false in 2.3 and true in 4.0.3
}
I'm testing the same code in two different devices and the funny thing is, the cookies are set (and also transferred between launches of the application) correctly in 4.0.3 but not in 2.3.3. When I say they are not set, I mean that hasCookies() returns false and also getCookie() returns null when I provide the URL.
I've tried every possible combination for the Cookie URL when calling setCookie: "http://alpha.mydomainname.com", "http://www.mydomainname.com", "http://mydomainname.com", "mydomainname.com", "alpha.mydomainname.com", ".mydomainname.com", "www.mydomainname.com", none of them works. Please help.
I recently had a similar problem, and the following solution worked for me. I create/get instances of CookieSyncManager and CookieManager at the beginning, and use them throughout the code, instead of creating new instances again. I also had to experiment with setting the cookie on the correct domain - I had to set it to the domain that appears in one of the redirects.
final CookieSyncManager cookieSyncManager = CookieSyncManager.createInstance(context);
final CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
cookieManager.removeSessionCookie();
//Save the two cookies: auth token and session info
List<Cookie> cookies = httpclient.getCookieStore().getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
String cookieString = cookie.getName() + "=" + cookie.getValue() + "; Domain=" + cookie.getDomain();
cookieManager.setCookie("http://mydomainname.com", cookieString);
}
cookieSyncManager.sync();
}
I've faced the same problem. There is not so clear how to use the setCookie method. You should use it with some loop if you have a few items with cookies (like in my case):
val cookies = "key1=someValue1;key2=someValue2;key3=someValue3"
val cookiesList = cookies.split(";")
cookiesList.forEach { item ->
CookieManager.getInstance().setCookie("http://someHost.com", item)
}
So you can't use it like:
CookieManager.getInstance().setCookie("http://someHost.com", "key1=someValue1;key2=someValue2;key3=someValue3")
I also ran into some strange behaviours with CookieManager, eventually I ended up with a solution that is a workaround - but it works.
Instead of using CookieManager I just used the http cookie headers, so for example using HttpUrlConnection it can look like that:
//Save the two cookies: auth token and session info
List<Cookie> cookies = httpclient.getCookieStore().getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
String cookieString = cookie.getName() + "=" + cookie.getValue();
myHttpURLConnection.setRequestProperty("Cookie", cookieString);
}
Of course, if you need to persist these cookies you will have to do it wourself and save their value somewhere for later use...
The cookie can't include the semicolon, because the semicolon means separator in cookies.
I want to logout my twitter account by deleting the cookies created by it. I am able to retrive the cookies created by twitter using code:
String twit_cookie = getCookie ("http://www.twitter.com");
But how can i delete only cookies created by twitter because removeAllCookie() deletes all the cookies created by browser. How can i delete the specific cookie by URL or by name???
Please help...
CookieManager class has a method setCookie. Have you tried it like:
setCookie("http://www.twitter.com", null);
Or perhaps
setCookie("http://www.twitter.com", "auth_token=''");
You can use the method CookieManager#setCookie(String url, String value). As stated in the docs:
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 "clearest" way is to set all cookies created by twitter to expired (a time in the past). The code from this answer is almost right, except the date is in the future.
Modified code:
final String domain = "http://www.twitter.com";
CookieSyncManager.createInstance(this);
CookieManager cookieManager = CookieManager.getInstance();
String cookiestring = cookieManager.getCookie(domain); //get all cookies
String[] cookies = cookiestring.split(";");
for (int i=0; i<cookies.length; i++) {
String[] cookieparts = cookies[i].split("="); //split cookie into name and value etc.
// set cookie to an expired date
cookieManager.setCookie(domain, cookieparts[0].trim()+"=; Expires=Wed, 31 Dec 2000 23:59:59 GMT");
}
CookieSyncManager.getInstance().sync(); //sync the new cookies just to be sure
I have a server that uses spring security remember-me-authentication to which I login using Android DefaultHttpClient in a POST method.
I am able to successfully login and even able to retrieve the session cookies created (In my case a jsessionid cookie and a spring security remember me cookie).
But the weird thing is after executing the POST method like
mResponse = mDefaultHttpClient.execute(mHttpPost)
I am able to retrieve the cookies, but only using getCookieStore method in my DefaultHttpClient like
mDefaultHttpClient.getCookieStore()
not using getAllHeaders method of the HttpResponse object
headers = mResponse.getAllHeaders();
HeaderIterator headerIterrator = new BasicHeaderIterator(headers, null);
while (headerIterrator.hasNext()) {
Header header = headerIterrator.nextHeader();
headerStringBuilder.append(" " + header.getName() + ":" + header.getValue());
}
Log.e("Post response headers: ", headerStringBuilder.toString());
I get some headers back in here( Server, X-powered-By, Date, Content-Type, Content-Length) but not the Set-Cookie header or a few others( Access-control-Allow-* etc)
Thanks for any help!
UPDATE: Looks like the DefaultHttpClient does not expose some of the headers. I tried adding response interceptor (like shown below) and getAllHeaders returned all the headers I wanted. Thanks for reading my question!
mDefaultHttpClient.addResponseInterceptor(new HttpResponseInterceptor() {
public void process(final HttpResponse response, final HttpContext context)
throws HttpException, IOException {
Header[] headers = response.getAllHeaders();
for (int i = 0; i < headers.length; i++) {
Header header = headers[i];
Log.e("HTTP: ", "name: " + header.getName());
Log.e("HTTP: ", "value: " + header.getValue());
}
}
});
Did you try using HttpURLConnection rather than HttpClient? HttpClient, as the name says, is a client, then it manages cookies for you, HttpURLConnection does not.
Doc says "HTTP clients encapsulate a smorgasbord of objects required to execute HTTP requests while handling cookies, authentication, connection management, and other features."
if you set cookie in server side , like session_start() in php , the Set-Cookie have show in the headers , but if you have don't set any cookie , the Set-Cookie have not shown.
after:
05-25 17:23:16.616: I/HTTP:(575): name: Set-Cookie
05-25 17:23:16.616: I/HTTP:(575): value: PHPSESSID=g29i01av8ddvpgsi7lpaj12lc3; path=/