I am trying to connect to foodEssentials API and it sends a cookie.
I am getting the error of Cookie rejected: "BasicClientCookie ..."
How do I deal with cookies coming in or is there any examples as I have looked around and found this loopj
I am not sure what I should do. Does the browser handle the cookie or the application?
Browsers handle server side cookies by themselves.
In case of Android application, developer need to explicitly handle the cookies.
Here is an example of handling cookies : http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/httpclient/src/examples/org/apache/http/examples/client/ClientFormLogin.java
You can use the CookieStore class of Apache http client. Somewhere in your code initialization, create a cookie store and http context:
BasicCookieStore cookieStore = new BasicCookieStore();
httpContext = new BasicHttpContext();
httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
The cookie store will manage all the cookies as long as httpContext is alive.
So later, when doing a request, you just give the context to the httpClient:
AndroidHttpClient httpClient = AndroidHttpClient.newInstance(httpAgent);
HttpGet request = new HttpGet(url);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String json = httpClient.execute(request, responseHandler, httpContext);
... and the cookies will be properly managed.
See Android Http Client and Basic Cookie Store.
Related
I know there are plenty of resources like this on the web, and the closest I've come was the answer to this question: ASP.NET Web API Authentication.
Basically, this is my requirement. Log in via android to my account on an MVC4 internet application I created (which uses SimpleMembership). It is NOT an MVC Web Api app, which seems to confuse things when looking at the various ways of achieving this.
I am attempting to use FormsAuthentication to set an authentication cookie, but I have no idea how to configure my android httpclient to actually send through this authentication cookie, or how to get MVC to save a session from my android app.
So far, this is what I've come up with on the MVC side:
[HttpPost]
[AllowAnonymous]
public bool LoginMobi(LoginModel model)
{
var membership = (SimpleMembershipProvider)Membership.Provider;
if (membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, false);
return true;
}
else return false;
}
And I use the following java in my android app (sent over an SSL connection):
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("https://mysite/api/login");
List<NameValuePair> nameValue = new ArrayList<NameValuePair>();
nameValue.add(new BasicNameValuePair("UserName", "foo"));
nameValue.add(new BasicNameValuePair("Password", "bar"));
httppost.setEntity(new UrlEncodedFormEntity(nameValue));
httppost.setHeader("Content-type", "application/json");
HttpResponse response = httpclient.execute(httppost);
// etc etc
What I haven't figured out is how to receive the authentication cookie on android and send it back with each request to controllers with the [Authorize] attribute. I'm rather new to this so please forgive my ignorance!
You are using FormsAuthentication which uses cookie to identify user for each request. You have two options here.
Use CookieStore for HttpClient. Check Android HttpClient and Cookies
OR
Combine BASIC auth and FormsAuthentication. Check Combining Forms Authentication and Basic Authentication
Hope this helps.
Is there a simple way to make sure the HttpClient does not send the cookies during a request, without removing all cookies.
By doing:
httpClient.getCookieStore().clear();
cookies are not sent, which is good.
But for other requests (where I need those cookies), I don't want to fetch new cookies again.
You can try to set the Cookie header of the request manually for that particular request
request.setHeader("Cookie","");
Edited:
So if is that not working an other approach could be to try to add an empty cookie store to that HttpClient instance, so theoretically you will have an empty cookiestore
// Create a local instance of cookie store
CookieStore cookieStore = new BasicCookieStore();
// Add the created cookieStore to the http client instance
httpClient.setCookieStore(cookieStore);
My response is based on assumption that you are using Apache HttpClient version 4.x.
By default HttpClient 4.x introduces two protocol interceptors to the protocol processing pipeline responsible for HTTP state management: RequestAddCookies and ResponseProcessCookies. What you want is to remove RequestAddCookies while leaving ResponseProcessCookies in place.
This is how this can be done with HttpClient 4.3
CloseableHttpClient httpclient = HttpClients.custom()
.disableCookieManagement()
.addInterceptorFirst(new ResponseProcessCookies())
.build();
There are other ways to achieve the same result such as using a custom protocol interceptor that removes cookie headers from all outgoing requests, but removal of RequestAddCookies is the most efficient.
How can I disable/ignore default cookie handling of httpclient. I want to do it manually. I want to set a pre-defined cookie header for all http requests.
The latest httpclient (4.5.1) has a method called "disableCookieManagement", and it appears this just disables the internal cookie management, not the ability to send or receive cookies, and is working for me-
http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/client/HttpClientBuilder.html#disableCookieManagement()
Set httpclient.setCookieStore(cookieStore); before you execute your HttpClient
Force to setup the HttpContext before executing the request:
private HttpClientContext httpContext = new HttpClientContext();
httpContext.setCookieStore(new BasicCookieStore());
The setCookieStore will create an empty cookie store to replace the default cookie store of http connection.
After that we can execute the http method:
org.apache.http.client.HttpClient.execute(HttpUriRequest, HttpContext)
Also we can reuse the cookie store (hold the BasicCookieStore) to keep the connection alive.
I could not find a way to disable/ignore cookie handling by DefaultHttpClient in Andoroid(I should have explored more into Android source code but have a time limitation). But I resolved it by removing all cookies before doing httpClient.execute() like this -
((AbstractHttpClient) myDefaultHttpClient).getCookieStore().clear();
This removes all the cookies stored by the defaultHttpClient and then you can manually handle(add/delete) cookies using -
myHttpPost.setHeader("Cookie", myCookie);
Hope it helps.
I'm a junior developer who has been working on a RSS Reader.
I'm trying to download a webpage from my app for offline viewing but I am having a few issues.
When I try to download an asp page I don't seem to get the right content, but instead a html page with asp form widgets.
Can anyone help me with understanding what's going on and how I could possibly download the content of the page?
I should also mention the webpage is a sharepoint webpage using https ssl authentication, using httpclient as my means to connect and download the webpage.
To communicate with ASP you usually need to send __VIEWSTATE and _EVENTVALIDATION tokens in your HttpPost and other requests. You can get those once by calling HttpGet on the basic page and using Patten with regexes or a simple str.contains("_VIEWSTATE") and strip it out of the HTML and send with every request.
If you're not doing any POSTs, just basic GETs, then make sure you're setting the headers appropriately, as so:
HttpGet req = new HttpGet("YOUR SITE'S URL");
req.setHeader("Content-Type", "application/x-www-form-urlencoded");
req.setHeader("Host", "YOUR SITE'S ROOT PAGE");
req.setHeader("User-Agent", "Mozilla/5.0 ...");
req.setHeader("Accept-Encoding", "gzip,deflate,sdch");
req.setHeader("Accept", "text/html,application/xhtml+xml,application/xml");
req.setHeader("Accept-Language", "en-us,en");
req.setHeader("Accept-Charset", "ISO-8859-1,utf-8");
HttpResponse resp = client.execute(req, localContext);
Don't forget about the possible session cookie you can store in httpcontext and also pass in with every execute as seen above:
CookieStore cookieStore = new BasicCookieStore();
HttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
The best way to go about it in theory is to download Fiddler, run the site in Chrome, see what's going on and emulate actual browser requests in your app: http://www.fiddler2.com/fiddler2/
Would it be possible to setup an HttpClient such that on a website that updates periodically, perhaps due to AJAX, the resulting changes would be captured by the HttpClient. Similar to keeping a connection to a website alive, and if there were an update, the HttpClient would send the updated response to a listener of some type. I feel as if there is an obvious answer to my question, but I just haven't found it because I may have some of my terminology wrong...
This is just an example snippet of how I usually set up a connection:
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse response = httpClient.execute(httpGet);
Welcome to Stack Overflow! I do not think keeping a constant connection open to your site would be the best solution. Why don't you just poll every once in awhile?