Sharing cookies/session from WebView to HttpClient doesn't work - android

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.

Related

Get Session from Android Webview

I have created an Android application, in that I want to get Session from webview.
How to make it possible ?
Thanks.
I use this method for getting session cookies from a webview:
public static String getCookieFromAppCookieManager(String url) throws MalformedURLException {
CookieManager cookieManager = CookieManager.getInstance();
if (cookieManager == null)
return null;
String rawCookieHeader = null;
URL parsedURL = new URL(url);
rawCookieHeader = cookieManager.getCookie(parsedURL.getHost());
if (rawCookieHeader == null)
return null;
return rawCookieHeader;
}
There are two ways:
If a developer has made a httpclient, and makes an api auth call and store the cookie. Then you sync the httpclient's cookie with webview and maintain a session natively.
If user has used a webview to make an auth call and the cookie resides in the webview.
First one is your code and simply making a getter will return instance of DefaultHTTPClient. The instance will have access to cookies too. you can make async calls to auth api to get correct cookie in the instance. Make sure to keep HttpClient and Webview in sync.
For retrieving cookie in second method, you would use CookieManager object and the url which user is logged into and you need cookie for, example twitter.com See the second post here for implementation details.

How to find the request type loadUrl method in android?

I am developing an android web app which uses web view. And to load a page I am using the loadUrl method in webview. Is there a way by which I can know the request type of the URL being loaded? I understand that the when I use loadUrl, somewhere internally it is making a http connection. So how I know the request type of that connection?
I tried adding the below just before I call loadUrl, but it always returns "GET" as it seems to make its own new connection and therefore its a GET by default.
//Get the request type
try {
URL actualUrl = new URL(url);
HttpURLConnection cn = (HttpURLConnection) actualUrl.openConnection();
methodName = cn.getRequestMethod();
// It always returns a "GET" for the above.
view.loadUrl(url);
if you can Want to take some help than use this file ( detail , you can send parameters with the help of this file ) :
https://www.dropbox.com/s/0nmvn1pxxcsh3ah/WebCallableCoreActivity.java
else use this code :
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(this.url_string);
HttpResponse response = (HttpResponse) httpClient.execute(httppost);

Website login and keep session cookies

I am trying to scrape some content form a website but you must be logged in order to view specific content. I want make a login using user id & password and keep session cookies on: m.amway.com i tried using Jsoup.... however after using the code below i realize that Jsoup cannot read javascript which is what the website is based on....
Does anyone have a method i could use to login, keep session cookie, and scrape content, using something other than Jsoup? Thanks in advance.
public String Jlogin(String User, String Pass) throws Exception{
String title = "didnt work";
Response logRes = Jsoup.connect(AmwayURL)
.data("userid", User)
.data("userpswd", Pass)
.method(Method.POST)
.execute();
// get all cookies
Map<String, String> cookies = logRes.cookies();
Document doc1 = logRes.parse();
String sessionId = logRes.cookie("JSESSIONID");
Document doc2 = Jsoup
.connect("https://m.amway.com/business/volume/pvbv/inquiry.ashx")
.cookie("jsessionid", sessionId).get();
System.out.println(doc2);
title = doc2.toString() + "................." + sessionId;
return title;
}
You can use a much larger API called HttpClient.
has the following classes:
- HttpGet
- HttpPost
- HttpEntity
- HttpResponse
HttpResponse reads Javascript from any page, as follows:
EntityUtils.toString(HttpResponse.getEntity());
for more details on how to use the API, check this link (Extremly helps):
http://www.codeblues.in/blog/?p=5

Using HttpGet returning complete HTML code

I am trying to invoke a private web-service in which there's one link I've to access using GET method. While using the direct URL on browser (needs to login first), I get the data in JSON format. The URL I am invoking is like this
http://www.example.com/trip/details/860720?format=json
The url is working fine, but when I invoke this using HttpGet, I am getting the HTML coding of the webpage, instead of the JSON String. The code I am using is as follows:
private String runURL(String src,int id) { //src="http://www.example.com/trip/details/"
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(src);
String responseBody="";
BasicHttpParams params=new BasicHttpParams();
params.setParameter("domain", token); //The access token I am getting after the Login
params.setParameter("format", "json");
params.setParameter("id", id);
try {
httpget.setParams(params);
HttpResponse response = httpclient.execute(httpget);
responseBody = EntityUtils.toString(response.getEntity());
Log.d("runURL", "response " + responseBody); //prints the complete HTML code of the web-page
} catch (Exception e) {
e.printStackTrace();
}
return responseBody;
}
Can you tell me what am I doing wrong here??
Try specify Accept & Content-Type in you http header:
httpget.setHeader("Accept", "application/json"); // or application/jsonrequest
httpget.setHeader("Content-Type", "application/json");
Note that you can use tools like wireshark capture and analyse the income and outcome http package, and figure out the exact style of the http header that returns your json response from a standard browser.
Update:
You mentioned need login first when using browser, the html content returned is probably the login page (if use basic authentication type, it returns a short html response with status code 401, so a modern browser knows how to handle, more specifically, pop up login prompt to user), so the first try would be checking the status code of your http response:
int responseStatusCode = response.getStatusLine().getStatusCode();
Depend on what kind of authentication type you use, you probably need specify login credentials in your http request as well, something like this (if it is a basic authentication):
httpClient.getCredentialsProvider().setCredentials(
new AuthScope("http://www.example.com/trip/details/860720?format=json", 80),
new UsernamePasswordCredentials("username", "password");

Android: Unable to login to a web session and parse XML data using DOM on the same login session

Android Development: I'm needing to log into a web session using POST, then make another request of which I parse XML to get Lat/Long, then submit this to a google maps overlay.
My issue is I'm able to log into my system, but when I submit a command to parse XML, it is acting like a completely new session and I basically get an 'incorrect login' reply from the server.
Does anyone have some simple steps to perform this...and to keep a session open for as many commands as I need? I'm not actually SURE I'm using a session cookie, but believe this is the case.
Some example code may be:
try {
URI loginUri = new URI("http://www.mywebsite.com/ExternalLogin.jsp?user=lee&pwd=bluedog");
URI xmlUri = new URI("http://www.mywebsite.com/getXMLInfo.xml");
// Prepares the request.
HttpClient httpClient = new DefaultHttpClient();
HttpGet loginHttpGet = new HttpGet();
loginHttpGet.setURI(loginUri);
HttpGet xmlHttpGet = new HttpGet();
xmlHttpGet.setURI(xmlUri);
// Sends the request and read the response
HttpResponse loginResponse = httpClient.execute(loginHttpGet);
InputStream loginInputStream = loginResponse.getEntity().getContent();
HttpResponse xmlResponse = httpClient.execute(xmlHttpGet);
InputStream xmlInputStream = xmlResponse.getEntity().getContent();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(xmlInputStream.toString()));
doc.getDocumentElement();
// Continue using DOM to parse my XML data
}
You don't indicate your how our "web session" is being maintained. I am going to guess it is via a session cookie. If so, use HttpClient and keep using the same HttpClient object for both requests. The session cookies will be handled automatically.

Categories

Resources