LoopJ AndroidAsyncHttp and Persistent cookie store - android

Inside my service I run this code:
public class MainService extends Service {
....
....
CookieManager mCookieManager = CookieManager.getInstance();
CookieSyncManager mCookieSyncManager = CookieSyncManager.createInstance(mContext);
if (mCookieSyncManager != null) {
mCookieSyncManager.sync();
}
AsyncHttpClient myClient = new AsyncHttpClient();
PersistentCookieStore myCookieStore = new PersistentCookieStore(mContext);
myClient.setCookieStore(myCookieStore);
myClient.setUserAgent("my service");
myClient.get("http://example.com/mypage/", new AsyncHttpResponseHandler() {
...
}
...
...
}
When I check my webserver logs, I can see cookies exists in request headers.
But these cookies are old cookies.
I also run this AndroidAsyncHttp code from an Activity. Same old cookies are sent.
But when I print out current cookies in my WebView, I see new cookies.
How can I send WebView's cookies with AndroidAsyncHttp ?

Clear cookie before set the cookie
myCookieStore.clear();
In my experience I don't need that CookieManager.
I only use this.
AsyncHttpClient myClient = new AsyncHttpClient();
PersistentCookieStore myCookieStore = new PersistentCookieStore(mContext);
// clear cookie to make the fresh cookie, to ensure the newest cookie is being send
myCookieStore.clear();
// set the new cookie
myClient.setCookieStore(myCookieStore);
myClient.get("http://example.com/mypage/", new AsyncHttpResponseHandler() {
...
}

Related

how to handle cookies for okhttpclient requests

I am sending a request to a website's webpage's url using OkHttpClient and storing the cookie it gives by the following method which I got from stackoverflow only.
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
ClearableCookieJar cookieJar = new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(this));
OkHttpClient client = new OkHttpClient.Builder()
.cookieJar(cookieJar)
.build();
Request request = new Request.Builder()
.url("www.example.com/homePage")
.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0")
.build();
It is necessary to store the cookie otherwise the website redirects the request to a timeout page.
Then, I see the html of the page to check whether I reached the correct URL.
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
textView.setText("Failed to get response");
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if(response.isSuccessful()){
//String myResponse contains the html of the webpage
final String myResponse = response.body().string();
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText(myResponse);
}
});
}
}
});
Now, I make another Request variable in a similar fashion to the URL "www.example.com/loginPage" and try to see the html but it redirects me to the timeout page because the request is made without sending the cookie which I got from the homePage.
So, in short, how can I get a cookie from "www.example.com/cookieProviderPage" and store it and then use that cookie for all further requests to all pages of that website. Pages of that website have different urls like "www.example.com/cookieRequiredPage1", "www.example.com/cookieRequiredPage2" etc.
P.S. - I have checked many stackoverflow questions related to cookies but I am unable to implement the them specifically to my case.
Cookies added with Command
new OkHttpClient.Builder()
.cookieJar(cookieJar)
are loaded depending on the CookieJar.loadForRequest method. You must check, how your implementation of the interface CookieJar implemented the loadForRequest method. If cookies are just loaded for exact the same url the cookies originally come from, you have the error.
If the cookies come from "www.example.com/cookieProviderPage" and you want to supply the cookies for the request "www.example.com/loginPage", your CookieJar implementation may only supply the cookies to requests with the url "www.example.com/cookieProviderPage".
This is for example the case, if Cookie.matches is used to the get the cookies for the request. Cookie.matches compares domain name and path of the url.

How to access cookie and check if it has expired using okhttp3 and PersistentCookieStore?

I am working on an Android app in which a log in post request is made to a webservice. The request returns a cookie which expires in 20 minutes.
Using okhttp3 and this PersistentCookieStore library, I got the cookie to be stored and subsequently added it as request header to access authentication-required get requests (e.g. personal information that are non-public).
The code goes this way,
CookieJar myCookieJar = new PersistentCookieJar(new SetCookieCache(),
new SharedPrefsCookiePersistor(this));
OkHttpClient client = new OkHttpClient.Builder().cookieJar(HttpRequests.cookieJar).build();
I then call a method like this inside an (after I have gone through another log in Async task to get the cookie) Async task to perform a get request that requires authentication,
public static String PostReq(String url, String json) {
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.addHeader("Cookie", "key=value")
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
catch(Exception e){
}
}
The .addHeader("Cookie", "key=value") adds the cookie to the header to tell the webservice that I am authenticated.
Here comes my difficulty. Since the cookie expires after 20 minutes, I would like to be able to access the cookie itself to check for the expiration time and possibly redirect the user to the log in activity by calling the method,
myCookie.expiresAt()
and comparing it to
System.currentTimeMillis()
I tried to look at the PersistentCookieStore codes and found that it uses a SharedPreference with the key "CookiePersistence". I looked inside this file while my emulator was running the app and found it to be empty however.
How would I be able to access this cookie that I have obtained? Much thanks for any advice to be given.
OK, this is old, but I was facing the same problem, and here is how I fixed it.
Hold a reference to your SetCookieCache used to instantiate your CookieJar:
SetCookieCache cookieCache = new SetCookieCache();
CookieJar myCookieJar = new PersistentCookieJar(
cookieCache,
new SharedPrefsCookiePersistor(this)
);
Then use this to find your cookie and check it:
for (Cookie cookie : cookieCache) {
if (cookie.name().equals("cookie_name") && cookie.persistent()) {
//cookie is still good
break;
}
}
Or use cookie.expiresAt() to do your thing.

How to implement cookie handling on Android using OkHttp?

Using OkHttp by Square https://github.com/square/okhttp, how can I:
Retrieve a cookie returned from the server
Store the cookie for upcoming requests
Use the stored cookie in subsequent requests
Update the cookie returned by the subsequent request
Ideally the cookie would be stored, resent and updated automatically with every request.
For OkHttp3, a simple accept-all, non-persistent CookieJar implementation can be as follows:
OkHttpClient client = new OkHttpClient.Builder()
.cookieJar(new CookieJar() {
private final HashMap<HttpUrl, List<Cookie>> cookieStore = new HashMap<>();
#Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
cookieStore.put(url, cookies);
}
#Override
public List<Cookie> loadForRequest(HttpUrl url) {
List<Cookie> cookies = cookieStore.get(url);
return cookies != null ? cookies : new ArrayList<Cookie>();
}
})
.build();
Or if you prefer to use java.net.CookieManager, include okhttp-urlconnection in your project, which contains JavaNetCookieJar, a wrapper class that delegates to java.net.CookieHandler:
dependencies {
compile "com.squareup.okhttp3:okhttp:3.0.0"
compile "com.squareup.okhttp3:okhttp-urlconnection:3.0.0"
}
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
OkHttpClient client = new OkHttpClient.Builder()
.cookieJar(new JavaNetCookieJar(cookieManager))
.build();
For OkHttp 3 (or maybe newer)
See hidro's answer
For OkHttp 2.x (or maybe older)
You can pass a CookieHandler to your OkHttpClient instance. You can use the CookieManager implementation from java.net or you could implement your own if you want. Choose the policy that works best for your needs.
OkHttpClient client = new OkHttpClient();
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
client.setCookieHandler(cookieManager);
OkHttp will save cookies received from Responses into the CookieHandler and read from it when sending requests. It will do so for matching request/response URIs.
I needed to share the default Cookie Jar (CookieManager.getInstance()) so this seemed to work ok for me.
return new CookieJar() {
#Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
CookieManager cookieManager = CookieManager.getInstance();
for (Cookie cookie : cookies) {
cookieManager.setCookie(url.toString(), cookie.toString());
}
}
#Override
public List<Cookie> loadForRequest(HttpUrl url) {
CookieManager cookieManager = CookieManager.getInstance();
List<Cookie> cookies = new ArrayList<>();
if (cookieManager.getCookie(url.toString()) != null) {
String[] splitCookies = cookieManager.getCookie(url.toString()).split("[,;]");
for (int i=0; i<splitCookies.length; i++) {
cookies.add(Cookie.parse(url, splitCookies[i].trim()));
}
}
return cookies;
}
};

Android get session cookie from webview

I have en app with a webview to display an e-shop website.
For various reason the login par is made in a native form with a DefaultHttpClient and HttpPost.
When the user start by login, i have no problème to save the session cookie from the request to the webview cookie store.
My problem is when the user first navigate through the webview an login after, i cant retrive the webview cookie session from the cookiestore to put it to my DefaultHttpClient
this is my code :
CookieSyncManager.createInstance(context);
CookieManager cookieManager = CookieManager.getInstance();
CookieSyncManager.getInstance().sync();
cookieManager.setAcceptCookie(true);
DefaultHttpClient client = new DefaultHttpClient(clientConnectionManager, params);
String[] keyValueSets = cookieManager.getCookie(context.getString(R.string.cookie_domaine)).split(";");
for(String cookie : keyValueSets)
{
String[] keyValue = cookie.split("=");
String key = keyValue[0];
String value = "";
if(keyValue.length>1) value = keyValue[1];
BasicClientCookie2 cookieForRequest = (BasicClientCookie2) new BasicClientCookie2(key, value);
cookieForRequest.setDomain(context.getString(R.string.cookie_domaine));
cookieForRequest.setPath("/");
client.getCookieStore().addCookie(cookieForRequest);
}
In debug i see my session cookie but the getCookie method dont return it, i think it's because the cookie session domain start with a dot.
How can i maintain my webview session to a DefaultHttpClient request?

WebView cookies in a HTTP Request

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

Categories

Resources