The command is
curl http://localhost:port -H 'Authorization: Token token=blahblahblah'
I am currently using this approach:
HttpClient httpclient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
String authString = "Token " + "3589c4cd8c18f077bf43b4c4b7415d"; // <~token
httpPost.setHeader("Authorization", authString);
HttpResponse response = httpclient.execute(httpPost);
HttpEntity entity = response.getEntity();
I just get a bad token back meaning that I did not successfully login from my android client. However the curl command i post works fine. So I believe I am not implementing the http Post correctly on my app. Thanks!
Your curl command has the header as:
Token token=blahblahblah
Your Java has the header as:
Token 3589c4cd8c18f077bf43b4c4b7415d
You are missing the token= part.
Also, HttpClient was deprecated in Android 5.1 and is removed from the Android SDK in Android 6.0. I encourage you to move to some other HTTP API. That could be:
the built-in classic Java HttpUrlConnection
Apache's independent packaging of HttpClient for Android
OkHttp (my recommendation)
AndroidAsync
Or, depending upon the nature of your HTTP work, you might choose a library that supports higher-order operations (e.g., Retrofit for Web service APIs).
Related
I am wondering after I searched in few books and on web that none of then detailed about it. I want to know that what exactly the purpose of below line individually while we parse JSON response file :
Lines ARE :
DefaultHttpClient client=new DefaultHttpClient();
HttpPost post = new HttpPost(Url);
HttpResponse response = client.execute(post);
HttpEntity entity = response.getEntity();
I know one thing that all together these four lines perform the connection with the server, but have no idea what individually the do.
I am sure I will get answer here from one of SOF besties.
Android's DefaultHttpClient Supports:
HTTPS, streaming uploads and downloads, configurable timeouts, IPv6 and connection pooling.
HttpPost :
The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line.
HttpResponse :
Takes care of the response that is got after executing client.execute(post);
Finally the following code obtains the message entity of this response.
response.getEntity()
Please check the android documentation for detailed implementation.
Code above is resposible for Http post request to server and get JSON response, so that you can parse and get required data.
Above 4 lines don't do JSON parsing. They only make an HTTP connection and the way of doing it is only recommended below Gingerbread. For Gingerbread and above use HttpURLConnection. More details here.
After you have the content (make a check if the response code is as expected - 200 or 201) you can proceed to JSON parsing. Use either Jackson, GSON or Android's json framework (this is my preferred order).
As per may Opinion
DefaultHttpClient client=new DefaultHttpClient(); responsible for HttpsURLConnection efficient(Connection) when connecting to up-to-date servers, without breaking compatibility with older ones.
HttpPost post = new HttpPost(Url); responsible for get POST request and send response.
HttpResponse response = client.execute(post); responsible for executes HTTP request using the default context.
HttpEntity entity = response.getEntity(); responsible for carry a content entity associated with the request or response.
For more information go to:http://hc.apache.org/httpcomponents-client-ga/tutorial/html/fundamentals.html
I have created an API controller to handle only json requests from an Android app. Naturally I'm using token authentication. What would be better:
To send a request using POST:
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://10.0.0.170:3000/api/get_all");
httppost.setHeader("content-type", "application/json; charset= utf-8");
httppost.setHeader("Accept", "application/json");
JSONObject json = new JSONObject();
json.put("token", token);
StringEntity entity = new StringEntity(json.toString(), "utf-8");
httppost.setEntity(entity);
HttpResponse response = httpclient.execute(httppost);
or GET:
httpget = new HttpGet("http://10.0.0.170:3000/api/get_all?"+"token="+token);
httpget.setHeader("content-type", "application/json; charset= utf-8");
httpget.setHeader("Accept", "application/json");
response = httpclient.execute(httpget);
result = EntityUtils.toString(response.getEntity());
clearly there is less code in GET, but is there some other reasons to prefer one over the other?
Even if you are using this token for simple lookup, i.e. without changing the state on server, use POST. If you use GET, web server will log all query parameters making it more vulnerable for log injection attacks for example.
You should also consider using HTTPS for authentication token in production.
In your code consider also handling return status from web server (e.g. when it is not 200).
In general, for the choice POST vs GET you can also refer to W3C:
Use GET if:
The interaction is more like a question (i.e., it is a safe operation such as a query, read operation, or lookup).
Use POST if:
The interaction is more like an order, or
The interaction changes the state of the resource in a way that the user would perceive (e.g., a subscription to a service), or
The user be held accountable for the results of the interaction.
I'm having problems with an app that works when connecting to a remote web server, running a php script against a database. However, when I point the same app to my local web server running on my machine, things doesn't work.
Here's the code I use for connecting to the remote web server (it needs authentication):
(All the networking code is done inside an AsyncTask class.)
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
StringBuilder authentication = new
StringBuilder().append("frankh").append(":").append("vriceI29");
result = Base64.encodeBytes(authentication.toString().getBytes());
httppost.setHeader("Authorization", "Basic " + result);
nameValuePairs.add(new BasicNameValuePair("date", date));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
For the connection to the local server, which doesn't use authentication, I'm commenting out these lines:
//StringBuilder authentication = new
// StringBuilder().append("frankh").append(":").append("vriceI29");
//result = Base64.encodeBytes(authentication.toString().getBytes());
//httppost.setHeader("Authorization", "Basic " + result);
However, I get two different errors, depending on how I phrase the url to the local web server.
If I use this url: "http://localhost.shoppinglistapp/fetchlist.php"
I get this error:
Error in http connectionjava.net.UnknownHostException: localhost.shoppinglistapp
If I skip the http part in the url, I get this error:
Error in http connectionjava.lang.IllegalStateException: Target host must not be null,
or set in parameters.
What am I doing wrong here? The remote server is a Linux Apache server, and the local server is IIS 7. The local server is supposed to be just for working on when I've got no or a bad internet connection, so it's not critical, but I hate not knowing why things doesn't work.
If you testing via your local emulator, you'll want to use 10.0.2.2 instead of 'localhost'.
Referring to localhost from the emulated environment
I want to build an Http Server which will serve the requests of a chat application in android. Because i am really confused... in my code I have to use sockets? How can i make the client to communicate with the server? Which is the code i have to add in the server in order to accept the requests from the client and respond to them? The code I use in the client is the following:
DefaultHttpClient client = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://localhost:80");
List< BasicNameValuePair > nvps = new ArrayList< BasicNameValuePair >();
nvps.add(new BasicNameValuePair("username", username1));
nvps.add(new BasicNameValuePair("password", password1));
try {
UrlEncodedFormEntity p_entity = new UrlEncodedFormEntity(nvps, HTTP.UTF_8);
httppost.setEntity(p_entity);
//Execute HTTP Post Request
HttpResponse response = client.execute(httppost);
Log.v(TAG,"something");
Log.v(TAG, response.getStatusLine().toString());
HttpEntity responseEntity = response.getEntity();
Please I really need an answer. Thank you!!!
Sockets (Socket for client, ServerSocket for server) is the most basic layer of communication. You chose TCP or UDP and over it, you need to encode all of your protocol.
There are also some libraries that encode higher level protocols (HTTP, FTP, and even higher as SOAP). If you use these libraries, you usually do not need to manage socket as it is done by the library itself (in the server you only specify port and optionally IP to bind to; in the client you specify host and port to connect to).
You can use different combinations (v.g. implementing your server with SOAP and then creating and sending a SOAP message from the client using Socket) but the simplest way is to use the same library both for the server and client.
About which one is better: it depends of what you want it to. Higher level libraries are more flexible but may take a time to master and may have more overhead, lower level needs that you manage everything. If there is no more compelling reason, I usually just use the HTTP protocol (both from the JVM or from the Apache Foundation projects).
I'm trying to authenticate an android client app to my server ruby on rails app which uses Devise gem. But I've tried http authentication, and post requests to authenticate, and the server just responds 200 for any given username/password.
I've already set up the config.http_authenticatable = true and the :database_authenticable at the user model...
I'll post my authenticate method so u guys can have a look on it...
public static boolean authenticate(User user, String verb) throws IOException, JSONException
{
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(verb);
CredentialsProvider credProvider = new BasicCredentialsProvider();
credProvider.setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),
new UsernamePasswordCredentials(user.getMail(), user.getPassword()));
httpClient.setCredentialsProvider(credProvider);
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("email", user.getMail()));
nameValuePairs.add(new BasicNameValuePair("password", user.getPassword()));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse httpResponse = httpClient.execute(httpPost);
int statusCode = httpResponse.getStatusLine().getStatusCode();
//JSONObject resp = null;
if (statusCode < 200 || statusCode >= 300){
throw new IOException("Error");
}
return true;
}
If server is responding 200, it really sounds like server side configuration, so you should double-check your URLs are actually secured, using a desktop web browser and a tool like Fiddler so you can see everything. Pay particular attention to the Authentication headers, and the Status codes; at the least you should see a 401 from the server to start things off.
You can also turn on diagnostics for Apache HTTP on your device, and it will also dump headers and content to LOGCAT, so you can make sure everything is proceeding.
Check the WWW-Autnenticate header's contents, it will specify which schemes are accepted. The client side will re-request the URL, but it will put the Authorization header into its request.
In short, make sure your server side works outside of your application, in an environment that's easier to troubleshoot.
Client side, it looks like you are only activating BASIC authentication (everyone stop using it!), and your endpoint may only want DIGEST or NTLM or KERBEROS or any other authentication scheme than BASIC. Since it looks like you didn't set up for SSL, certainly use at least DIGEST or you have clear text issues!
Using form variables (for authentication) only works at the application level, and not the HTTP protocol level, which uses HTTP Headers (WWW-Autnenticate, Authorization) and Status codes (401, 403) for the authentication process. And again, if you aren't configuring your server (and client) for SSL-only, there will be clear text problems.