Server not Recognising Cookie From Android Phone - android

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.

Related

Android HttpClient to accept all cookies

I'm pretty new in the Android world and maybe my question is very simple..
I have an android app where I use HttpGet to connect to a server and collect data.
However the server sometimes sets some cookies that are not remembered by my code.
I found a post where its using a custom cookie policy and is accepting everything.. just what I need.But I cant implement it.As I understand my version of java httpclient is old and does not have the functions I need.
Here's my code:
try {
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(link);
get.getParams().setParameter(
ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
HttpResponse responseGet = client.execute(get,ctx);
status_code = responseGet.getStatusLine().getStatusCode();
HttpEntity resEntityGet = responseGet.getEntity();
if (resEntityGet != null) {
http_response = EntityUtils.toString(resEntityGet);
}
}
And the code I need to implement:
CookieStore cookieStore = new BasicCookieStore();
httpclient.setCookieStore(cookieStore);
CookieSpecFactory csf = new CookieSpecFactory() {
public CookieSpec newInstance(HttpParams params) {
return new BrowserCompatSpec() {
#Override
public void validate(Cookie cookie, CookieOrigin origin)
throws MalformedCookieException {
log.debug("allow all cookies");
}
};
}
};
httpclient.getCookieSpecs().register("easy", csf);
httpclient.getParams().setParameter(
ClientPNames.COOKIE_POLICY, "easy");
All I need is to set this csf policy to my client.
However it seems that I dont have these two functions in the library : setCookieStore and getCookieSpecs().register()
What are my options to run it ?!

Django: resetting password without a CSRF token

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();

How to maintain session in android using an HttpClient

I am using an HttpClient to make server connection, like this:
DefaultHttpClient client = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.example.com/login");
HttpResponse response = client.execute(httppost);
The server session works with cookies.
And to maintain session I have to use the same client for all the subsequent connections. Which I am doing and works fine.
But the problem is, in android usually Activity data is destroyed when there is a need, which destroys the HttpClient too (when my application is in baclground) and hence the session is being lost.
Is there a way to make a HttpClient persistent? Or how do I solve this case?
Thank You.
There is no way as I know to save your session and recreate after Activity relaunch.
The only one way is to put your HttpClient code to Service. By this way you can play with activities and do not worry about broken sessions.
You can find Services documentation here
The server session works with cookies.
for Android by default cookies are enable and you don't need to worry about.
For sure you can store Cookies but I don't see the reason that it can help you somehow for your question.
Anyways this is a technique to fetch Cookies:
List<Cookie> mCookies = null;
mCookies = httpclient.getCookieStore().getCookies();
if (mCookies.isEmpty()) {
Log.d("test_runner", "Cookies: None");
} else {
for (int i = 0; i < mCookies.size(); i++) {
System.out.println("- " + mCookies.get(i).toString());
Log.d("test_runner", "Cookies: [" + i + "]" + mCookies.get(i).toString());
}
}
And this is a way how to put them back:
CookieStore cookieStore = new BasicCookieStore();
for(Cookie cook : mCookies){
cookieStore.addCookie(cook);
}
httpclient = new DefaultHttpClient(params);
httpclient.setCookieStore(cookieStore);
The best idea is to put all the function that your server do in on unique class which is going to be call by the tasks which want to connect. I call this class WebServiceManager. This class have exactly the same method than the server.
As you want an unique session do :
private static WebServiceManager wsm = null;
public static WebServiceManager getInstance() {
if (wsm == null) {
wsm = new WebServiceManager();
}
return wsm;
}
private final HttpClient httpClient;
private WebServiceManager() {
httpClient=new DefaultHttpClient();
}
and then you call the method of your instance of webServiceManager to use always the same httpclient and you keep your cookies. :)

Is it possible to use AndroidHttpClient with PersistentCookieStore?

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);

self registration Grails access via http (Android Client)

People, I have a system written in grails that makes use of Spring Security Core plugin. Now I made an Android (Java) client to access some data via HTTP. At first my code was being blocked by the spring security when i was using this code below:
DefaultHttpClient httpClient = new DefaultHttpClient();
CredentialsProvider credProvider = new BasicCredentialsProvider(); credProvider.setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), new UsernamePasswordCredentials("LOGIN", "PWD");
httpClient.setCredentialsProvider(credProvider);
it was redirecting me to the login page, but then a friend of mine configured the server and the client to use BASIC HTTP authorization, and it worked, the client sent the request, and the response was OK. But now my login page is not working, if the user is not logged in it is showed a default "basic" login/password screen to him, and not my customized login page.
if it is of any help the client code that "works" is below...
// HTTP Authentication
// Type of authentication
List<String> authPrefs = new ArrayList<String>(2);
authPrefs.add(AuthPolicy.BASIC);
httpclient.getParams().setParameter("http.auth.scheme-pref", authPrefs);
httpclient.getCredentialsProvider().setCredentials(new AuthScope(urlHost, urlPort),new UsernamePasswordCredentials("login", "pwd"));
//Preemptive mode
BasicHttpContext localcontext = new BasicHttpContext();
BasicScheme basicAuth = new BasicScheme();
localcontext.setAttribute("preemptive-auth", basicAuth);
httpContext = localcontext;
AbstractHttpMessage method = null;
method = new HttpGet(urlStr);
method.setParams(new BasicHttpParams().setParameter(urlStr, url));
// Now Execute:
HttpResponse httpResponse = httpclient.execute((HttpUriRequest) method, httpContext);
Does this help you out? This shows how you can use basic auth for some sections of your Grails web-app (where a generic window asks for username and password) and the "regular" login form for others (default web login page).
http://grails-plugins.github.com/grails-spring-security-core/docs/manual/guide/single.html#9.1%20Basic%20and%20Digest%20Authentication

Categories

Resources