Is it possible to use the cookies of a WebView in a HTTP Request? If yes, how can I do that?
Thanks
CookieManager is what you are looking for!
CookieSyncManager.createInstance(context)
Create the manager
CookieSyncManager.getInstance().startSync()
in Activity.onResume(), and call
CookieSyncManager.getInstance().stopSync()
in Activity.onPause().
To get instant sync instead of waiting for the timer to trigger, the host can call
CookieSyncManager.getInstance().sync()
Note that even sync() happens asynchronously, so don't do it just as your activity is shutting down.
Heres how you might go about using it:
// use cookies to remember a logged in status
CookieSyncManager.createInstance(this);
CookieSyncManager.getInstance().startSync();
WebView webview = new WebView(this);
webview.getSettings().setJavaScriptEnabled(true);
setContentView(webview);
webview.loadUrl([MY URL]);
Referenced from this question
EDIT:
If you wanted to do it with a HttpClient, you would need to create an HttpContext.
// Create a local instance of cookie store
CookieStore cookieStore = new BasicCookieStore();
// Create local HTTP context
HttpContext localContext = new BasicHttpContext();
// Bind custom cookie store to the local context
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
HttpGet httpget = new HttpGet("http://www.google.com/");
System.out.println("executing request " + httpget.getURI());
// Pass local context as a parameter
HttpResponse response = httpclient.execute(httpget, localContext);
Referenced from this question
Related
I have a Django website that manages Users. Using the built-in functionality, users can request a password reset from the website and that works great. I have implemented it according to this tutorial so I am using the built-in password reset functionality.
I have an Android app from which users should also be able to request a password reset. The problem is that I do not have a CSRF token in the application, and the the built-in password_reset method has the #csrf_protect decorator. This means that I cannot access it without a CSRF token and I also can't modify it with the #csrf_exempt decorator.
So the next idea is to create a function, which generates a CSRF token, stores it in the request and redirects to the correct URL which sends the reset email. The problem is that according to this, django does not allow to pass POST parameters further in a redirect.
Therefore my question is how can I request a password reset in Django without a CSRF token? Alternatively, what is the correct way to request this from an application?
I found a solution myself. Please feel free to post any alternative solutions. One that doesn't require two separate requests would be particularly great.
If you look at the password_reset method, you can see that it only tries to process the request as a reset request if the request method is POST. Otherwise it just returns a TemplateResponse containing a form. This also contains the CSRF token as a cookie.
So first, I send a GET request to http://myaddress.com/user/password/reset/ and extract the CSRF cookie from the response. Then I send a POST request containing the cookie, the email address and 2 headers (see below).
This is the code I've implemented to achieve this from Android (trimmed):
String url = "http://myaddress.com/user/password/reset/";
GET Request:
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
CookieStore cookieStore = new BasicCookieStore();
HttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
HttpResponse httpResponse = httpClient.execute(httpGet, localContext);
Cookie csrfCookie = null;
for (Cookie cookie : cookieStore.getCookies()) {
if (cookie.getName() == "csrftoken") {
csrfCookie = cookie;
break;
}
}
if (csrfCookie == null) {
throw new NullPointerException("CSRF cookie not found!");
}
return csrfCookie;
Note that you want the CookieStore from org.apache.http.client.
POST Request:
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpPost httpPost = new HttpPost(url);
// Prepare the cookie store to receive cookies.
CookieStore cookieStore = new BasicCookieStore();
cookieStore.addCookie(csrfCookie);
httpPost.setHeader("Referer", url);
httpPost.setHeader("X-CSRFToken", csrfCookie.getValue());
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addTextBody("email", emailAddressToReset);
httpPost.setEntity(builder.build());
HttpResponse httpResponse = httpClient.execute(httpPost, localContext);
if (httpResponse.getStatusLine().getStatusCode() != 200) {
throw new Exception("Could not reset password!");
}
Toast.makeText(context, "Password reset requested! Please check your email inbox!", Toast.LENGTH_LONG).show();
I would like to use AndroidHttpClient instead of DefaultHttpClient.
In the documentation is say:
This client processes cookies but does not retain them by default. To retain cookies, simply add a cookie store to the HttpContext:
context.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
Where do I get this context from???
Should I get it from the AndroidHttpClient or should I create it first and then pass it?
AndroidHttpClient client = AndroidHttpClient.newInstance(...);
HttpContext ctx = new BasicHttpContext();
ctx.setAttribute(...);
HttpGet get = new HttpGet(...);
client.execute(get, ctx);
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.
I am developing server client application on android and i am using session on server side of application but sometimes i lost my session on server.
Ps: i use https connection on server.
I am using these to hold session:
I am using single instance DefaultHttpClient and use it for all http requests.
I use only httpPost method
I use only https certificate:
schemeRegistry.register(new Scheme("https", sslSocketFactory, 443));
ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
I save my cookies after all http requests:
private void createSessionCookie(){
List<Cookie> cookies = httpclient.getCookieStore().getCookies();
if (! cookies.isEmpty()){
CookieSyncManager.createInstance(ctx);
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(UrlConstants.SERVICE_PRE_URL, cookieString);
CookieSyncManager.getInstance().sync();
}
}
}
Even though i am doing these, i lose session.
Please help me to solve this problem,
Thanks for any advice
Best Regards.
You should not do anything with cookies manually, just create static CookieStore somewhere, assign it to the HttpContext, and use that context in your requests. Cookies will be saved and restored automagically.
These are your class members:
private static CookieStore cookieStore = new BasicCookieStore();
private HttpClient httpclient = new DefaultHttpClient();
private HttpPost post = new HttpPost("your url here");
And this part goes into the member function, which does the request:
HttpContext ctx = new BasicHttpContext();
ctx.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
HttpResponse result = httpclient.execute(post,ctx);
I am trying to connect to a drupal server. I have been able to do this in the past but the drupal developers now require me to add another cookie. The server does not register the cookie that I am trying to send below. Can anybody see why?
public static void maybeCreateHttpClient() {
if (mHttpClient == null) {
mHttpClient = new DefaultHttpClient();
final HttpParams params = mHttpClient.getParams();
HttpConnectionParams.setConnectionTimeout(params,
REGISTRATION_TIMEOUT);
HttpConnectionParams.setSoTimeout(params, REGISTRATION_TIMEOUT);
ConnManagerParams.setTimeout(params, REGISTRATION_TIMEOUT);
BasicCookieStore cookieStore = new BasicCookieStore();
ClientCookie cookie = new BasicClientCookie("aml", key);
cookieStore.addCookie(cookie);
localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
}
}
It turns out that, I didn't need to use cookie, cookstore or httpcontent. As far as I can understand these are mainly used to managed cookies coming from the server.
I managed to solve my problem by setting a header like so
String key = "whatever";
post.addHeader("Cookie", "aml=" + key);
This can be used on httppost, httpget or httput.
That took me a few days for such a simple solution. I hope it helps somebody else out
Oh, well if you're looking for why the cookies weren't added, you weren't getting or adding the cookie store from the http client. You should get the cookie store from the client, add your cookies, and then execute your request.