I'm trying to log into an https website with my Android app. The website returns a response code of 302 if the log in was successful and 200 if the log in was unsuccessful. I've researched how to use AndroidHttpClient and looked at examples, but I haven't been able to see any difference between my code and theirs. No matter what username and password I send to the website, I get a response code of 200 back -- even if the combination is correct. Do I have to do something special since the website uses secure http? Here is my code. I really appreciate any help.
public void login(String url, String username, String password){
CookieStore cookieStore;
HttpContext httpContext;
HttpGet httpGet;
HttpResponse httpResponse;
HttpPost post;
AndroidHttpClient httpClient;
cookieStore = new BasicCookieStore();
httpContext = new BasicHttpContext();
httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
httpClient = AndroidHttpClient.newInstance("Android");
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("name", username));
params.add(new BasicNameValuePair("pass", password));
params.add(new BasicNameValuePair("form_id", "user_login"));
httpGet = new HttpGet(url);
post = new HttpPost(url);
try {
post.setEntity(new UrlEncodedFormEntity(list, HTTP.UTF_8));
httpResponse = httpClient.execute(httpGet, httpContext);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Log.i("My App", httpResponse.getStatusLine().getStatusCode());
}
You should use POST instead of GET because GET will automatically handle the redirect, but:
If the 302 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.
Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
Edit: On further inspection, it looks like the KVP were being passed into the HttpPost but the HttpGet was being used for the request, so the username/password wouldn't have been passed to the server at all.
Sometimes overthinking things does lead one in the right direction though
Related
I have a problem with Androids HttpClient / HttpRequest that's really giving me headache.
The program should login on a website (it's actually working and login is successful). After it's logged in, I want it to get another path of the site, but I don't know how to stay logged in for the next call. The site is using cookies and i tried four different examples that i found on stackoverflow, but nothing helped me.
The code I have is:
HttpClient loginclient = new DefaultHttpClient();
HttpPost loginpost = new HttpPost("EXAMPLEURL");
//Parameters
List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>();
nameValuePair.add(new BasicNameValuePair("cookieuser", "1"));
nameValuePair.add(new BasicNameValuePair("vb_login_username", "EXAMPLE"));
nameValuePair.add(new BasicNameValuePair("vb_login_password", "EXAMPLE"));
nameValuePair.add(new BasicNameValuePair("do", "login"));
nameValuePair.add(new BasicNameValuePair("submit", "anmelden"));
// Url Encoding the POST parameters
try {
loginpost.setEntity(new UrlEncodedFormEntity(nameValuePair));
}
// Making HTTP Request
try {
HttpResponse response = loginclient.execute(loginpost);
String responseString = new BasicResponseHandler().handleResponse(response);
System.out.println(responseString);
}
PS: I removed the catch statements to make the code more clear
I am trying to send a HTTP Post request in Android application.
This is what should I send:
This is what should I receive:
So, to conclude, I need to get cookies from response and response code should be 302.
I have a following Android code:
private static String makePostRequest() {
HttpClient httpClient = new DefaultHttpClient();
// replace with your url
HttpPost httpPost = new HttpPost("http://g1.botva.ru/login.php");
boolean flag = httpClient.getParams().isParameterTrue(ClientPNames.HANDLE_REDIRECTS);
httpPost.addHeader("Accept", "*/*");
httpPost.addHeader("Accept-Encoding", "gzip, deflate");
//httpPost.addHeader("Content-Length", "83");
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
httpPost.addHeader("User-Agent", "runscope/0.1");
Header [] arr = httpPost.getAllHeaders();
String result123 = "";
//Post Data
List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(5);
nameValuePair.add(new BasicNameValuePair("do_cmd", "login"));
nameValuePair.add(new BasicNameValuePair("server", "1"));
nameValuePair.add(new BasicNameValuePair("email", "avmalyutin#mail.ru"));
nameValuePair.add(new BasicNameValuePair("password", "avmalyutin1234"));
nameValuePair.add(new BasicNameValuePair("remember", "1"));
//Encoding POST data
try {
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePair));
} catch (UnsupportedEncodingException e) {
// log exception
e.printStackTrace();
}
//making POST request.
try {
HttpResponse response = httpClient.execute(httpPost);
String getCookie = response.getHeaders("Pragma").length + "";
result123 = response.getStatusLine().getStatusCode()+"";
// write response to log
Log.d("Http Post Response:", response.toString());
} catch (ClientProtocolException e) {
// Log exception
e.printStackTrace();
} catch (IOException e) {
// Log exception
e.printStackTrace();
}
return result123;
}
And I receive code 200. And there is only PHPSESSIONID in Cookies, but there are no other cookies.
You will need to instrument the DefaultHttpClient so that you can see the WIRE and the HEADERS.
Google log WIRE HEADERS for the client you are using. If you can not figure out the logging debug ( you may want to consider DIFF client )
Then, compare the 2 frameworks doing the post (your test harness VS android ) just narrowing the differences between what headers + POST BODY are being sent. As you get android to converge with your test harness, the android will produce the same 302 result you report getting from the test harness.
Adding function
con.setInstanceFollowRedirects(false);
resolve the problem and it stops redirecting. And also I received code 302 as desired.
Thanks everybody for help
I'm trying to use cookies to hold my session on my Android app, but it seems I'm getting something wrong, because I never receive the expected response from my server.
At first I have a login routine that runs as expected and return all expected data.
My login request:
HttpContext httpContext = new BasicHttpContext();
HttpResponse response;
HttpClient client = new DefaultHttpClient();
String url = context.getString(R.string.url_login);
HttpPost connection = new HttpPost(url);
connection.setHeader("Content-Type","application/x-www-form-urlencoded");
List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(2);
nameValuePair.add(new BasicNameValuePair(PARAM_LOGIN,params[0]));
nameValuePair.add(new BasicNameValuePair(PARAM_PASSWORD,params[1]));
connection.setEntity(new UrlEncodedFormEntity(nameValuePair,"UTF-8"));
response = client.execute(connection,httpContext);
data = EntityUtils.toString(response.getEntity());
After I've my response I just make what ever I need with the data and then things start to fall a part. Because now I'm just trying to call my server in the same AsyncTask to test if my cookies got properly saved on my HttpContext.
At first I've just called my URL without any change, just reusing my current HttpContext:
HttpPost httpPost = new HttpPost(context.getString(R.string.url_cookie_test));
HttpResponse response = client.execute(httpPost, httpContext);
Since this test fails I tested to add my cookie value on my HttpPost header:
httpPost.addHeader(context.getString(R.string.domain),PHPSESSID+"="+cookieID+";");
Then I tried creating a new HttpContext and force the COOKIE_STORE:
CookieStore cookieStore = new BasicCookieStore();
BasicClientCookie cookie = new BasicClientCookie(PHPSESSID, cookieID);
cookieStore.addCookie(cookie);
HttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
HttpResponse response;
HttpClient client = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(context.getString(R.string.url_cookie_test));
response = client.execute(connection,localContext);
All fails, and I've already confirmed that when I first receive my login response I got the data expected from the cookies as can see below:
List<Cookie> cookies = ((AbstractHttpClient) client).getCookieStore().getCookies();
for (Cookie cookie: cookies){
Log.i("Cookie Value",cookie.toString());
/*
Prints:[[version: 0][name: PHPSESSID][value: 2ebbr87lsd9077m79n842hdgl3][domain: mydomain.org][path: /][expiry: null]]
*/
}
I've already searched on StackOverflow and I've found a ton of solutions that doesn't really worked for me, will share all solutions I've already tried:
Android: Using Cookies in HTTP Post request
HttpPost request with cookies
Sending cookie with http post android
Apache HttpClient 4.0.3 - how do I set cookie with sessionID for POST request
As I told you, here you are this piece of code in order to make httpPost to a server developed in Spring MVC, with an API REST. Please, consider to build your request on this way:
Please, pay attention to the comments. You should adapt it to your case ;). You can also enclose this code into a method or whatever you prefer.
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("yourPath");
//NameValuePairs is build with the params for your request
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
httppost.setHeader("Content-Type",
"application/x-www-form-urlencoded");
CookieStore cookieStore = new BasicCookieStore();
//cookie is a variable that I stored in my shared preferences.
//You have to send in it every request
//In your case, JSESSIONID should change, because it's for Java.
//Maybe it could be "PHPSESSID"
BasicClientCookie c = new BasicClientCookie("JSESSIONID", cookie);
//JSESSIONID: same comment as before.
httppost.setHeader("Cookie", "JSESSIONID="+cookie);
cookieStore.addCookie(c);
((AbstractHttpClient)httpclient).setCookieStore(cookieStore);
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
} catch (Exception e) {
Log.e("log_tag", "Error in http connection" + e.toString());
}
I hope this helps!! It was hard to find it among "old" projects :)
I want to make an application for a web page that needs POST login. After that I'll download an HTML page and read its tags and perform some tasks to display some information.
Before I begin, I want to know if there is a way login in to this page using POST, somehow programmatically and download the page.
this is a way to send post request:
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.example.com/login.php");
try
{
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("name", "value"));
Httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
String result = EntityUtils.toString(response.getEntity());
}
catch(Exception e)
{
e.printStackTrace();
}
you can send your information in order to login to page.!
I want to send the JSON text {} to a web service and read the response. How can I do this from android? What are the steps such as creating request object, setting content headers, etc.
My code is here
public void postData(String result,JSONObject obj) {
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpParams myParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(myParams, 10000);
HttpConnectionParams.setSoTimeout(myParams, 10000);
String json=obj.toString();
try {
HttpPost httppost = new HttpPost(result.toString());
StringEntity se = new StringEntity(obj.toString());
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
httppost.setEntity(se);
HttpResponse response = httpclient.execute(httppost);
String temp = EntityUtils.toString(response.getEntity());
Log.i("tag", temp);
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
}
what mistake i have done plz correct me because it shows me an bad request error
but when i do post in poster it shows me status as Successfull 200 ok
I do this with
httppost.setHeader("Content-type", "application/json");
Also, the new HttpPost() takes the web service URL as argument.
In the try catch loop, I did this:
HttpPost post = new HttpPost(
"https://www.placeyoururlhere.com");
post.setHeader(HTTP.CONTENT_TYPE,"application/json" );
List<NameValuePair> nameValuePairs = new
ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("json", json));
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpClient client = new DefaultHttpClient();
HttpResponse resp = client.execute(post);
HttpEntity entity = resp.getEntity();
response = EntityUtils.toString(entity);
You can add your nameValurPairs according to how many fields you have.
Typically the JSON might become really huge, which I will then suggest gzipping it then sending, but if your JSON is fairly small and always the same size the above should work for you.
If it is a web service and not RestAPI call then, you can get the WSDL file from the server and use a SOAP Stub generator to do all the work of creating the Request objects and the networking code for you, for example WSClient++
If you wish to do it by yourself then things get a little tricky. Android doesn't come with SOAP library.
However, you can download 3rd party library here: http://code.google.com/p/ksoap2-android/
If you need help using it, you might find this thread helpful: How to call a .NET Webservice from Android using KSOAP2?
If its a REST-API Call like POST or GET to be more specific then its is very simple
Just pass a JSON Formatted String object in you function and use org.json package to parse the response string for you.
Hope this helps.