Send token with HTTP POST from android to cakephp - android

i am sending data from an android device to my cakephp website through HTTP Post in json object ..like this
HttpPost post = new HttpPost("https://www.mywebtest.com/test");
and then i decode the json and extract the data like this
if ($this->request->isPost()){
$json = $this->request->data('json');
$data = json_decode($json, TRUE);
but at the moment i am not checking that whether the http post or data is coming from my android app or someone else .so if someone knows the url he can do something malicious ..because at times now the url which i have written in httpPost when i typed this url in my browser there is nothing is shown on the browser.. i want to display some kind of error or 404 page if some one typed the url in browser.. Essentially, you can say i am creating with CakePHP is an API, What i want to do is secure the API so only my app can execute requests.so i want to implement some type of authentication .. doing some research i come up to a solution that pass another parameter as a secret token from android app and then check token from my webapp and then extract data .. i dont know how can i pass another parameter in httppost and then check it on my webpage .. and also if that possible i want to randomly generate the token and encrypt it on every request and then decrypt it through key in webapp whenever the data is posting from android to webapp.. if someone has done before this or have an idea then please share code or any link.

Create a JsonObject for parameters,
JSONObject parametersList = new JSONObject();
put your parameters into that JSONObject
parametersList.put("testID", 123);
int androidValue = 231231231; // a identifer or password your choice.
parametersList.put("androidValue", androidValue);
and add list to your HttpPost
HttpPost request = new HttpPost("https://www.mywebtest.com/test");
request.setHeader(HTTP.CONTENT_TYPE, "application/json; charset=utf-8");
request.setEntity(new StringEntity(parameters.toString(), HTTP.UTF_8));
On the php side;
<?php
$postdata = $HTTP_RAW_POST_DATA;
$data = json_decode($postdata);
$id = $data->testID;
$androidValue = $data->androidValue;
if(androidValue == 231231231)
{
$json = "{d:[{sample1:'".$id."',sample2:'value12'}]}";
$response = $_GET["callback"] . $json;
echo $response;
}
else
{
// send failed data
}
?>
And this how to get respond on android side
HttpResponse response = client.execute(request);
final int statusCode = response.getStatusLine().getStatusCode();
final String jsonResponse = EntityUtils.toString(response.getEntity());
if (statusCode != HttpStatus.SC_OK) {
Log.w(TAG, "Error in web request: " + statusCode);
Log.w(TAG, jsonResponse);
return null;
} else {
Log.i(TAG, jsonResponse);
return jsonResponse;
}
I hope this will help.

Try with RequestHandler isMobile().
You will get true, if request is from mobile phone.
http://book.cakephp.org/2.0/en/core-libraries/components/request-handling.html#RequestHandlerComponent::isMobile

Related

Sending POST json from Android and receiving on Django

I am trying to get an android app to interact with a server in Django.
The app is trying to POST "json" data to Django. However, I am unable to receive the object on the Django end.
The value of request.POST is <QueryDict: {}> although the data sent isn't blank. Following is the code snippet for POST request from android.
public static String POST(String url,JSONObject obj){
InputStream inputStream = null;
String result = "";
try{
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
String json = obj.toString();
StringEntity se = new StringEntity(json);
httpPost.setEntity(se);
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type","application/json");
HttpResponse httpResponse = httpClient.execute((HttpUriRequest)httpPost);
inputStream = httpResponse.getEntity().getContent();
if(inputStream!=null){
result = convertInputStreamToString(inputStream);
}else{
result = "Did not work!";
}
}catch(Exception e){
}
return result;
}
EDIT:
Earlier, I was getting CSRF error and handled it this way (I haven't worked with Django enough to know if this is correct way to handle CSRF error)
#csrf_exempt
def search(request):
logger.debug(request.POST)
"""Code for JSON object processing"""
Any help with rectifying the problem would be highly appreciated.
OK I'm not very fluent in java but it seems to me that your request is well formed.
I think the issue is that you are sending the data as a json string instead of as if it was a raw form. When you do it this way, the data is not displayed in request.POST but in request.body as what it is: a json string, not form-like data.
So I think you have to take one of these ways:
send the data from the Android app as a form (not json-like). This way you'll see it in request.POST or
translate request.body into a dict and work with it instead of request.POST
Hope this helps! :)

http request to password protected files

The php files on my server are password protect with htaccess. How can I make request to these files through my android app?
I couldnt find any relevant answers with google search.
Here you can find your answer:
Basic HTTP Authentication on Android
Basically:
HttpUriRequest request = new HttpGet(YOUR_URL); // Or HttpPost(), depends on your needs
String credentials = YOUR_USERNAME + ":" + YOUR_PASSWORD;
String base64EncodedCredentials = Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
request.addHeader("Authorization", "Basic " + base64EncodedCredentials);
HttpClient httpclient = new DefaultHttpClient();
httpclient.execute(request);
// You'll need to handle the exceptions thrown by execute()
You can replace the last line with:
EDITED:
You can try someting like this:
try {
HttpResponse response = httpclient.execute(request);
//this is the login response, logged so you can see it - just use the second part of the log for anything you want to do with the data
Log.d("Login: Response", EntityUtils.toString(response.getEntity()));
} catch (IOException e) {
//if something went badly wrong
}
So you can view your response, maybe the problem is parsing the JSON.
Assuming your PHP files are protected by HTTP Basic Authentication, you can request your php files using this special URL syntax:
http://validuser:validpassword#www.domain.com/validfile.php

Android HttpPost request exception

Just as a demonstration the code will work, I am attempting to fetch some JSON data within my oncreate function. I know it should run on a different thread but I want to be sure the code successfully fetches my JSON before moving it into it's own thread.
The code is below:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
/***************************************************/
final String TAG = "PostFetcher";
final String SERVER_URL = "http://kylewbanks.com/rest/posts";
// final String TAG = "PostsActivity";
// List<Post> posts;
try {
//Create an HTTP client
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(SERVER_URL);
//Perform the request and check the status code
HttpResponse response = client.execute(post);
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
try {
//Read the server response and attempt to parse it as JSON
Reader reader = new InputStreamReader(content);
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setDateFormat("M/d/yy hh:mm a");
Gson gson = gsonBuilder.create();
List<JsonObject> posts = new ArrayList<JsonObject>();
Log.e(TAG, "Checking: " + posts);
// posts = Arrays.asList(gson.fromJson(reader, JsonObject[].class));
content.close();
} catch (Exception ex) {
Log.e(TAG, "Failed to parse JSON due to: " + ex);
}
} else {
Log.e(TAG, "Server responded with status code: " + statusLine.getStatusCode());
}
} catch(Exception ex) {
Log.e(TAG, "Failed to send HTTP POST request due to: " + ex);
}
}
When I run the code, I get the second to last exception message:
Server responded with status code: 500
Can anyone please tell me what I'm doing wrong?
You are sending a HttpPost request to (obviously) an website that uses RESTful styled API.
This means, it works with HTTP Verbs (GET, POST, PUT, DELETE).
If you want to read data and the read access never changes data, use GET.
If you want to update or replace data, user PUT or POST (put usually to replace, POST to change/add). However, JavaScript does (or did) only support GET and POST requests, so keep that in mind.
If you want to delete a resource or collection, use DELETE.
That being said: If you want to load data, use Get in your case HttpGet instead of HttpPost.
Also read more about RESTful web APIs.
Edit:
In fact, calling the given URL in Fiddler2 (as stated in the comment on the other answer) results a HTML website reporting the error:
You called this URL via POST, but the URL doesn't end in a slash and
you have APPEND_SLASH set. Django can't redirect to the slash URL
while maintaining POST data. Change your form to point to
kylewbanks.com/rest/posts/ (note the trailing slash), or set
APPEND_SLASH=False in your Django settings.
Its internal server error..check if there are any exceptions are getting thrown at server side.
It has nothing to do with your android code, the problem is at server.
You can use AsyncTask to run network/filesystem related operations.

I cannot seem to find out if this webservice is getting the JSON object sent from Android

I have a android application which sends JSON information to a webservice for it to validate the information. I am using Kate as an editor for the webservice. The concept of JSON and php webservices is new to me. I normally code in java.
JSONObject jsonObject = new JSONObject();
String userID = "";
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(loginURI);
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 10000);
HttpConnectionParams.setSoTimeout(httpParams,10000);
try {
jsonObject.put("username", username);
Log.i("username", jsonObject.toString());
jsonObject.put("password", password);
Log.i("password", jsonObject.toString());
StringEntity stringEntity = new StringEntity(jsonObject.toString());
stringEntity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
httpPost.setEntity(stringEntity);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity entity = httpResponse.getEntity();
if (entity != null) {
userID = EntityUtils.toString(httpResponse.getEntity());
Log.i("Read from server", userID);
}
}catch (IOException e){
Log.e("Login_Issue", e.toString());
}catch (JSONException e) {
e.printStackTrace();
}
return userID;
}
I found the StringEntity code online and thought it will work. I do not understand the purpose of the StringEntity for the HttpPost.
This is my webservice written in php.
include('dbconnect.php');
$tablename = 'users';
//username and password sent from android
$username=$_POST['myusername'];
$password=$_POST['mypassword'];
//protecting mysql injection
$username = stripslashes($username);
$password = stripslashes($password);
$username = mysql_real_escape_string($username);
$password = mysql_real_escape_string($password);
#$array = array($username,$password);
$sql = "SELECT first_name FROM $tablename WHERE u_username='$username' AND u_password=MD5('$password')";
//Querying the database
$result=mysql_query($sql);
if(!$result){
die(mysql_error();
}
//If found, number of rows must be 1
if((mysql_num_rows($result))==1){
//creating session
session_register("$username");
session_register("$password");
print true;
}else{
print false;
}
mysql_close();
I am not quite sure if the 'username' and the 'password' is being sent correctly from the android app to the webservice. How can I verify this? And is the webservice and the java code well-written to send the information in JSON?
When I go the webservice on the browser, I get the following error:
Parse error: parse error in E:\wamp\www\mobile.dcl.mu\webserver\login.php on line 24
Thank you in advance.
You try to bite off too much. It should be, like, 6 different questions (or just pay someone to write the scripts for you, or spend some time learning the technologies in isolation). Two first things to fix:
fix the parse error! it is as if you had a Java source that does not compile. The error is that you forgot the closing paren after die (mysql_error();
no, it will not work anyway. You send the data in the body as application/json, and you try to read it as url-encoded form. Decide which you want, ask for help on that.
remove the stripslashes. It does not add any security and will cause errors if anyone is using a slash in her password. Unless you have magic_quotes on, which you should not.
Since you made the three very basic mistakes so early, I am practically sure that there is much, much more to fix. Other than rewriting the whole thing for you or sending some general links on PHP programming and web application programming - I see no more way to help you. If you manage to split the problem, test things in isolation and ask more questions, there might be hope.
UPDATE
If you decide to standardize around JSON, the general pattern in your PHP files will be:
// get the body of the HTTP request (that's the "http entity")
$body = file_get_contents('php://input');
// translate JSON into ordinary PHP array:
$entity = json_decode($test, true);
// Now you can read parts of it as if you read an array;
// the data may be nested and will mirror exactly your JSONObject:
$username=$entity['myusername'];
$password=$entity['mypassword'];
[yes, that's me begging for an upvote :-)]
[and I think there is more problems in your Java code, but one thing at a time]

Using HttpGet returning complete HTML code

I am trying to invoke a private web-service in which there's one link I've to access using GET method. While using the direct URL on browser (needs to login first), I get the data in JSON format. The URL I am invoking is like this
http://www.example.com/trip/details/860720?format=json
The url is working fine, but when I invoke this using HttpGet, I am getting the HTML coding of the webpage, instead of the JSON String. The code I am using is as follows:
private String runURL(String src,int id) { //src="http://www.example.com/trip/details/"
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(src);
String responseBody="";
BasicHttpParams params=new BasicHttpParams();
params.setParameter("domain", token); //The access token I am getting after the Login
params.setParameter("format", "json");
params.setParameter("id", id);
try {
httpget.setParams(params);
HttpResponse response = httpclient.execute(httpget);
responseBody = EntityUtils.toString(response.getEntity());
Log.d("runURL", "response " + responseBody); //prints the complete HTML code of the web-page
} catch (Exception e) {
e.printStackTrace();
}
return responseBody;
}
Can you tell me what am I doing wrong here??
Try specify Accept & Content-Type in you http header:
httpget.setHeader("Accept", "application/json"); // or application/jsonrequest
httpget.setHeader("Content-Type", "application/json");
Note that you can use tools like wireshark capture and analyse the income and outcome http package, and figure out the exact style of the http header that returns your json response from a standard browser.
Update:
You mentioned need login first when using browser, the html content returned is probably the login page (if use basic authentication type, it returns a short html response with status code 401, so a modern browser knows how to handle, more specifically, pop up login prompt to user), so the first try would be checking the status code of your http response:
int responseStatusCode = response.getStatusLine().getStatusCode();
Depend on what kind of authentication type you use, you probably need specify login credentials in your http request as well, something like this (if it is a basic authentication):
httpClient.getCredentialsProvider().setCredentials(
new AuthScope("http://www.example.com/trip/details/860720?format=json", 80),
new UsernamePasswordCredentials("username", "password");

Categories

Resources