I have this scenario which my app shows in a webView a 2-page login process.
The first page asks only to which domain to you plan on connecting.
The second page asks for the credentials.
I'm trying to perform the login in the webView and then execute requests from my native code.
I realize I need to get the stored cookie from the webView (but from which url? from the first page or the second one?), and then use the cookie for the native code requests.
Can someone please tell me how to go about it? The login process is easy - the user logs in through the webview - fine. Now, I know how to use the cookie manage but I dont know which cookie am I suppose to look for - is it the url of the first login page? is it the second one? does it matter?
Next, how do I use the cookie to send back to server with a GET request so the server will know I'm authenticated?
I appreciate the answers I'm clueless and begging for help :)
Since the accepted answer does not really describe how it is done:
Put these lines somewhere where your app starts:
CookieHandler.setDefault(new CookieManager()); // Apparently for some folks this line works already, for me on Android 17 it does not.
CookieSyncManager.createInstance(yourContext); // or app will crash when requesting cookie
And then in your connection:
String cookies = CookieManager.getInstance().getCookie(urlString);
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
// conn.setRequestMethod("GET");
// conn.setDoInput(true);
if (cookies != null)
conn.setRequestProperty("Cookie", cookies);
// Starts the query
conn.connect();
I have done the opposite of you: I log in with loopj Android Asynchronous Http Client, and want the session cookies to apply to a webview, for the same website. I don't know if it will help you, but, I am going to post my code for copying over the cookies. Maybe seeing the process will help you to look for the items you need... to copy cookies from webview, to HTTP. I can't offer further help, since I'm fairly new at Android. (And, of course, I adapted my code from other people's posts.)
Class variable declarations:
private AsyncHttpClient loopjClient = new AsyncHttpClient();
private PersistentCookieStore myCookieStore;
onCreate() initialization:
myCookieStore = new PersistentCookieStore(this);
loopjClient.setCookieStore(myCookieStore);
After HTTP login:
// get cookies from the generic http session, and copy them to the webview
CookieSyncManager.createInstance(getActivity().getApplicationContext());
CookieManager.getInstance().removeAllCookie();
CookieManager cookieManager = CookieManager.getInstance();
List<Cookie> cookies = myCookieStore.getCookies();
for (Cookie eachCookie : cookies) {
String cookieString = eachCookie.getName() + "=" + eachCookie.getValue();
cookieManager.setCookie("http://www.example.com", cookieString);
//System.err.println(">>>>> " + "cookie: " + cookieString);
}
CookieSyncManager.getInstance().sync();
// holy ****, it worked; I am automatically logged in for the webview session
Note that loopj is like the webview, in that all cookie management and sending are automatic. I just copy all cookies for the domain. I think you'd be fine, doing the same... thus, no worry about whether from the first or second page.
At the end I found my way and it was pretty simple.
Once the user logs in through the webview - a cookie is set on the device.
Later on once I want to perform Native api calls on the service I ask the cookie manager for the cookie that was set based on the url.
I then take the important header that is used to authenticate on the server and send it along with my api calls.
Related
I have a Xamarin Forms app where I share cookies between the Webview and HttpClient by grabbing them after a login. On iOS this works fine, on Android I have the following issue:
If the cookie is created as the result of a HTTPClinet Api call, then deleted (expired) using either a WebView or HttpClient the cookie is no longer in the cookie list. When using HttpClient the HttpClientHandler.CookieContainer has a count of 0.
If the cookie is created using a WebView and deleted using another WebView the cookie is no longer in the cookie list.
If the cookie is created using a WebView and deleted using a HTTPClient Api call the expiration does not happen and the cookie is still in the HttpClinet's HttpClinetHandler's CookieContainer, I can see that the count is not 0.
If I look at the HttpResponse I see the expired cookie in the header:
"MyTestCookie=; expires=Wed, 28-Feb-2018 21:25:08 GMT; path=/; HttpOnly"
If I look further into the CookieContainer the m_domainTable has 2 entries, one for my ip with no cookies, and one for my ip preceded with a "." that contains the cookie that should be expired/deleted but it is not expired and has the original value.
The server code that creates the cookie for both the Api call and MVC Page is:
var cookie = new HttpCookie("MyTestCookie");
cookie.HttpOnly = true;
cookie.Values["token"] = "309d530f956ac04";
cookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(cookie);
and the code that Deletes / Expires it is:
if (Request.Cookies["MyTestCookie"] != null)
{
var cookie = new HttpCookie("MyTestCookie");
cookie.HttpOnly = true;
cookie.Expires = DateTime.Now.AddDays(-1);
Response.Cookies.Add(cookie);
}
Is this a bug, or am I missing something?
I am almost dead doing this.Need help.
My Requirement :-
I am developing an android app and want to use the cookies(/session) from webview in my java code. I basically want to get the html of other pages of an url after login in webview without opening those pages in webview but through my java code.
What I tried :-
For this I tried HttpClient and HttpURLConnection referring many SO questions but failed.
Can anybody please give me a sample code?
Say I have cookies in a hashmap cookies. How Can I use HttpClient and HttpURLConnection or anything else to get the other page html. The website I am trying with is https:
Please give a sample code
If I am right u are trying to use your webview's cookies to get other pages of site in your activity java code.if yes try this:
BufferedReader reader = null;
try {
URL url2 = new URL("url");
URLConnection con = (URLConnection) url2.openConnection();
CookieManager.getInstance().setAcceptCookie(true);
con.setRequestProperty("Cookie",CookieManager.getInstance().getCookie("logged in url in webview"));
con.setDoOutput(true);
con.connect();
reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
StringBiffer html;
String line = "";
while ((line = reader.readLine()) != null) {
html.append(line);
}
} catch (Exception e) {
e.printStackTrace();
}
It worked for me.
Have you tried to add the cookie as a HTTP header? I am not sure if I have understood you right but you can consider these:
Cookies: If you want to load some resource (no matter if it is a web page, image, css, js or something else) you are making a HTTP request. If the server keeps a session for your user, you are probably given a session cookie. The cookie must be sent with each request to the server as e COOKIE header. So if you want to pass the cookie to your request, add it as a header. Android provides you an easy way to do this with the CookieManager class. You can refer to this.
SSL: If you are trying to access a secured web site (https) you have to use an SSL certificate. Android comes up with a bunch of predistributed certificates for most of the popular web cites (e.g Facebook, Google, Twitter, etc.). You can use them out of the box. If your SSL certificate is not presented, you have to add it manually. Read this for more information.
I hope this was useful :)
I'm making a progam on Android.
It has one button and one WebView. If I click the button, It send post message to a web server. (using httpurlconnection)
The webview load a page from the same server. I want to sync cookies between core and webview. I found the method from core to webview. But, I couln't find a method from webview to core.
I tried these order.
the page of webview is loaded.
read cookies from webview.
add these cookies to core cookies using HttpCookie.
URI uri = new URI(url);
HttpCookie httpCookie = new HttpCookie(cookie.getKey(), cookie.getValue());
((java.net.CookieManager) CookieHandler.getDefault()).getCookieStore().add(uri, httpCookie);
but It doesn't working. what is wrong? please advice me about it.
Thank you in advance.
you need to set the cookie to your HttpPost object as well, try this:
httpPost.setHeader("Cookie", "PHPSESSID=" + httpCookie.getValue());
where httpPost is an instance of org.apache.http.client.methods.HttpPost
I have an android application using a webview on which the user has to log in with username and password before being redirected to the page i would like to scrape data off with jsoup. Since the jsoup thread would be a different session the user would have to login again.
Now i would like to use the cookie received from the webview to send with the jsoup request to be able to scrape my data.
The cookie is being synced with cookiesyncmanager with following code. This is basically where I am stuck cause i dont know how to read out the cookie nor how to attach it to the jsoup request. Please help? :)
public void onPageFinished(WebView view, String url) {
CookieSyncManager.getInstance().sync();
The jsoup scrape I am doing after the user has logged in with something like this:
doc = Jsoup.connect("https://need.authentication.com").get();
Elements elements = doc.select("span.tabCount");
Element count = elements.first();
Log.d(TAG, "test"+(count));
I'm not an android developer but maybe you can try something like this:
final String url = "https://need.authentication.com";
// -- Android Cookie part here --
CookieSyncManager.getInstance().sync();
CookieManager cm = CookieManager.getInstance();
String cookie = cm.getCookie(url); // returns cookie for url
// ...
// -- JSoup part here --
// Jsoup uses cookies as "name/value pairs"
doc = Jsoup.connect("https://need.authentication.com").header("Cookie", cookie).get();
// ...
I hope this helps a bit, but as i said before: im no android developer (and code isn't tested!)
Here's some documentation:
CookieManager
CookieSyncManager
Jsoup Connection
In my browser, or in iOS, when I try to get the contents of a URL with encoded http authentication information in the form
http://myUser:myPassword#www.example.com/secure/area/index.html
It just works. I'm getting URLs from a web service, and I'd like to avoid trying to parse them up for their HTTP auth info if I can help it. Is there a way to do something similar in Android without actually parsing the URLs? Alternatively, what is the best way to go about that?
UPDATE:
I find that when I try to set the authentication information in an Authorization header, I get a very strange FileNotFoundException.
Here's the code I'm using:
URL url = new URL(urlString);
URLConnection connection;
String authority = url.getAuthority();
if (authority.contains("#")) {
String userPasswordString = authority.split("#")[0];
url = new URL(urlString.replace(userPasswordString + "#", ""));
connection = url.openConnection();
String encoded = new String(Base64.encode(userPasswordString.getBytes(), Base64.DEFAULT), "UTF-8");
connection.setRequestProperty("Authorization", "Basic " + encoded);
} else {
connection = url.openConnection();
}
InputStream responseStream = connection.getInputStream();
All the info seems to check out, I've verified the url is correct, the base64 string is correct, and the file is certainly on the server--I have no trouble at all opening it with Firefox, and Firebug shows all the right headers, matching what I've sent as far as I can tell. What I get though is the following error (url host changed to protect the innocent):
java.io.FileNotFoundException: http://a1b.example.com/grid/uploads/profile/avatar/user1/custom-avatar.jpg
at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1061)
Any idea what this is all about?
I looked into using HttpClient, but saw that in Issue 16041 it is recommended that we prefer URLConnection.
That looks like your browser is applying some extra rules to parsing the URL. In Android you can use HTTP Client's authentication mechanism such as BASIC and DIGEST to do the same things. Which one you choose is dependent on the server you are trying to authenticate against.
Here is a good page to get you started.
Unfortunately, on Android you can't pass the user info (username/password) in that format to either java.net.URL or HttpClient and have it work like in a browser.
I'd recommend using URI (see http://download.oracle.com/javase/1.5.0/docs/api/index.html?java/net/URI.html) to do this: pass your URL to the URI constructor that takes a String and then you can extract the user info (using getUserInfo()). You can then either use HttpClient's authorization classes (see http://developer.android.com/reference/org/apache/http/auth/package-summary.html) or build the basic auth header yourself (an example is given at http://www.avajava.com/tutorials/lessons/how-do-i-connect-to-a-url-using-basic-authentication.html).