Java/Wordpress REST API - Keep user authenticated? - java

I'm using the below code on my main activity to log the user into my app. The app's backend is Wordpress. The server returns a success message, and the user is authenticated, but as soon as I get to the next screen/activity, and attempt to have the user create a post to wordpress, the server returns the message
"Sorry, you are not allowed to create posts as this user."
Especially odd in this case because the user credentials I'm using to login are the admin user.
Any idea how I can fix this?
LoginActivity (my user logs in successfully):
private class UserNetwork extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... voids) {
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("username", "admin");
jsonObject.put("password", "123456");
} catch (JSONException e) {
e.printStackTrace();
}
OkHttpClient client = new OkHttpClient();
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON, jsonObject.toString());
Request request = new Request.Builder()
.url("http://myurl.com/wp-json/wp/v2/custom-plugin/login")
.post(body)
.build();
Response response = null;
try {
response = client.newCall(request).execute();
String resStr = response.body().string();
Log.i("The response is", String.valueOf(response));
int responseCode = response.code();
Log.i("Check response code", String.valueOf(responseCode));
if (responseCode == 200) {
Log.i("We're logged in!", String.valueOf(responseCode));
Intent i = new Intent(LoginActivity.this, DashboardActivity.class);
startActivity(i);
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
DashboardActivity (user attempts to create post, and 'Unauthorized' messsage is returned):
private class UserPosts extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... voids) {
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("title", "Our first post");
jsonObject.put("content", "this is a test");
jsonObject.put("status", "publish");
} catch (JSONException e) {
e.printStackTrace();
}
OkHttpClient client = new OkHttpClient();
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
// put your json here
RequestBody body = RequestBody.create(JSON, jsonObject.toString());
Request request = new Request.Builder()
.url("http://myurl.com/wp-json/wp/v2/posts")
.post(body)
.build();
Response response = null;
try {
response = client.newCall(request).execute();
String resStr = response.body().string();
Log.i("The response is", String.valueOf(response));
int responseCode = response.code();
Log.i("Check response code", String.valueOf(responseCode));
if (responseCode == 200) {
Log.i("Creating post!", String.valueOf(responseCode));
} else {
Log.i("Post not created.", String.valueOf(responseCode));
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}

The problem you're having is caused by HTTP protocol being stateless.
That means whenever you perform request, server treats you as a new entity.
In case of most authenticated requests, the client is responsible for storing the tokens issued by the server during the login, and then passing them to following requests.
When you are using the browser it is the client and usually is being responsible for handling this state (it ma also be a JavaScript code running in the browser).
In your code that is your responsibility to store this state.
While you're using OkHttp, you could use CookieJar and it would probably work. However in the end using user credentials to authenticate application is not the best idea and using extension that would allow you to specify credentials for an application as #faozi suggested would probably be a better solution.

You need to install and activate the Application Passwords plugin and then follow the instructions given
here.
But you don’t need to actually set up any Application Passwords for your users.

you need to authenticate it first : here
you can add code in WordPress file to authenticate it

Related

I got different results when call simple GET Request with curl and java okhttp

I call below URL using cURL
curl 'http://username:password#192.168.1.108/merlin/Login.cgi'
and I get proper response
{ "Session" : "0xb3e01810", "result" : { "message" : "OK", "num" : 200 } }
I get the same response from browser (directly open link), postman and even with NodeJs,
but I get response code 401 when send GET_Request to this url using okhttp in java
my java code with okhttp is
Request request = new Request.Builder()
.url("http://username:password#192.168.1.108/merlin/Login.cgi")
.build();
try {
com.squareup.okhttp.Response response = client.newCall(request).execute();
System.out.println(response.code());
} catch (IOException e) {
e.printStackTrace();
}
Use basic authentication. Having username and password in the url, separated with :, is the same as basic authentication. I tested and it's ok. my snippet is:
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url("http://192.168.1.108/merlin/Login.cgi")
.header("Authorization", "Basic " + Base64.getEncoder().encodeToString("username:password".getBytes()))
.get().build();
try (Response response = client.newCall(request).execute()) {
assert response.body() != null;
String res = response.body().string();
} catch (Exception e) {
e.printStackTrace();
}

How to send HTTP request from android app to Heroku

I have a android app that uses the twilio sdk and is hosted by heroku server. I'm trying to push a button in my app to send a HTTP request to heroku to send a REST API request to Twilio to update my twiml URL. The current way i'm trying to send the the HTTP request is not working. I have looked through all of the examples that i could find and none of them show how to do this function. Does anybody know how to do this? Thanks in advance.
This is my code for trying to send the HTTP request to heroku
holdButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://yourappnamehere.herokuapp.com/hello");
try {
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
HttpEntity ht = response.getEntity();
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
InputStream is = buf.getContent();
BufferedReader r = new BufferedReader(new InputStreamReader(is));
StringBuilder total = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
total.append(line);
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//setting a toast to see if this is being initiated
Toast.makeText(getBaseContext(), "why wont it work!", Toast.LENGTH_SHORT).show();
}
;
});
This is my updated code including the volley library
holdButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//setting up a request queue from Volley API
//RequestQueue mRequestQueue;
// Instantiate the cache
Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap
// Set up the network to use HttpURLConnection as the HTTP client.
Network network = new BasicNetwork(new HurlStack());
// Instantiate the RequestQueue with the cache and network.
mRequestQueue = new RequestQueue(cache, network);
// Start the queue
mRequestQueue.start();
String url = "http://yourappnamehere.herokuapp.com/hello";
// Formulate the request and handle the response.
StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// Do something with the response
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// Handle error
}
});
// Add the request to the RequestQueue.
mRequestQueue.add(stringRequest);
Toast.makeText(getBaseContext(), "why wont it work!", Toast.LENGTH_SHORT).show();
}
;
});
I would suggest using a library like Google Volley which is pretty slick
https://developer.android.com/training/volley/index.html
HttpRequest is deprecated from API level 22. It would be best practice to avoid using that. Use java.net.HttpUrlConnection instead.
However, if you still want to use it, the above code needs to be run on a thread other than the UI thread as mentioned in the comment above.

Accessing a login api using http get method in android

I am developing an android app which uses a login api, which will allow its web users to login with their same credentials on the android device.....
the url for the api is
https://api.ecoachsolutions.com/main.php?ecoachsignin=1&server=remote&user=ecoachguest&pass=ecoachguest
which retuns a response in json
JSON object: {
status: <success or error>,
msg: <response message>,
profile: <user profile object>
}
I tried this code which I found searching on the internet but it isn't working,
private void doLogin(View view) {
//ALERT MESSAGE
_spinner.setVisibility(View.VISIBLE);
Toast.makeText(mContext, "connecting to server.... ",
Toast.LENGTH_SHORT).show();
// URLEncode user defined data
String usernameValue = username.getText().toString();
String passValue = password.getText().toString();
// Create http cliient object to send request to server
HttpClient Client = new DefaultHttpClient();
// Create URL string
String URL = "https://api.ecoachsolutions.com/main.php?ecoachsignin=1&server=remote&user="+usernameValue+"&pass="+passValue;
Log.i("httpget", URL);
try
{
String SetServerString ;
// Create Request to server and get response
HttpGet httpget = new HttpGet(URL);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
SetServerString = Client.execute(httpget, responseHandler);
System.out.println(usernameValue);
System.out.println(passValue);
// Show response on activity
Toast.makeText(getBaseContext(),SetServerString,Toast.LENGTH_LONG).show();
}
catch(Exception ex)
{
Toast.makeText(getBaseContext(),"Fail",Toast.LENGTH_LONG).show();
_spinner.setVisibility(View.INVISIBLE);
}
}
will appreciate the help or the positive direction thanks :)
Change your code to get the HttpResponse like below,
String responseBody = "";
HttpResponse response = client.execute(post);
int responseCode = response.getStatusLine().getStatusCode();
Log.i("GET Response Code ",responseCode + "");
switch(responseCode) {
// Means server is responding
case 200:
HttpEntity entity = response.getEntity();
if(entity != null) {
responseBody = EntityUtils.toString(entity);
// Now you can try printing your returned string here, before you go for JSON parsing
}
break;
// Add more case statements to handle other scenarios
}
The code is simple, but if still unable to understand, don't hesitate to ask.

Http 500 Internal Server Error in Android

Android code
class BirthdayTask extends AsyncTask<String, String, String>{
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
try {
System.out.println(uri[0]);
response = httpclient.execute(new HttpGet(uri[0]));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
System.out.println("responseString"+responseString);
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
//TODO Handle problems..
} catch (Exception e) {
e.printStackTrace();
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
/* System.out.println(result);
System.out.println(result);
System.out.println(result);*/
}
}
#RequestMapping(value="here is my url" ,method=RequestMethod.GET)
public #ResponseBody String Test(HttpServletRequest req) {
Gson gson = new Gson();
Domain domain = (Domain)req.getSession().getAttribute("Domain");
List<UserProfile> userProfiles = userProfileManager.getUpcomingBirthday(domain.getDomainId(),15);
return gson.toJson(userProfiles);
}
Webservice
This is the webservice I am calling from browser its working fine. But when I call from Android then I get a 500 internal server error. But in server logs I see no error.
What is going wrong?
Whenever an HTTP code starts with a 5 (5xx), it means something got wrong on the server. It is not about your code here, on the android client side, but in the server side implementation.
This is webservice I am calling from broweser its woriking fine ....But when I am calling from android then 500 internal server error
This may mean the the request payload that you are sending from your android app, must be different to that when you do it from your browser. Please print your request payload and double-check everything. Additionally, it might help you also give the request headers a look.
It is hard to give an answer, but i think the session is null when you call the WS using Android. While if you call the WS using a browser the session could be mantained using cookie or sessionId i dont find any line of code that handles cookies or sessionId in some way.
IMO you shouldnt rely on session information.
Hope it helps you.
I recommend using retrofit instead of AsyncTask. It will solve the problem with a cookie.

receiving JSON response (android)

I am trying to send a JSON with the information email address, first and last names and expecting a response from the server to say {status: "Created"} or {status: "Resend"} and depending on the answer there would be a pop up message. I was wondering what I use to extract the information from the status class. Thanks!
Here is my code to accept
protected void sendJson(final String email, final String firstN,
final String lastN) {
Thread t = new Thread() {
public void run() {
Looper.prepare(); // For Preparing Message Pool for the child
// Thread
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(),
10000); // Timeout Limit
HttpResponse response;
JSONObject json = new JSONObject();
try {
// post in the url
HttpPost post = new HttpPost(
"https://iphone-radar.com/accounts");
json.put("email_address", email);
json.put("first_name", firstN);
json.put("last_name", lastN);
StringEntity se = new StringEntity("JSON: "
+ json.toString());
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,
"application/json"));
post.setEntity(se);
response = client.execute(post);
/* Checking response */
if (response != null) {
String str = response.getEntity().toString();
if (str.equals("Created")) {
new AlertDialog.Builder(CreateAccount.this)
.setTitle("Account Creation Successful")
.setMessage(
"An activation code has been sent to you. Please check your SPAM folder if you do not receive your activation code email")
.setNeutralButton("OK", null).show();
} else if(str.equals("Resend")) {
new AlertDialog.Builder(CreateAccount.this)
.setTitle("Code Resent")
.setMessage(
"Your activation code has been resent to your email.\n\nIf you are not receiving your activation code, our email is being blocked. Please email us at 'help#iphone-tracker.net' and we will manually send you a code.")
.setNeutralButton("OK", null).show();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
You should convert the response to a string, then create a JSONObject. You can then just access the JSON object's properties. Try this:
org.json.JSONObject obj = new org.json.JSONObject(org.apache.http.util.EntityUtils.toString(response.getEntity()));
if ("Created".equals(obj.getString("status"))) {
new AlertDialog.Builder(CreateAccount.this)
.setTitle("Account Creation Successful")
.setMessage(
"An activation code has been sent to you. Please check your SPAM folder if you do not receive your activation code email")
.setNeutralButton("OK", null).show();
} else if("Resend".equals(obj.getString("status"))) {
new AlertDialog.Builder(CreateAccount.this)
.setTitle("Code Resent")
.setMessage(
"Your activation code has been resent to your email.\n\nIf you are not receiving your activation code, our email is being blocked. Please email us at 'help#iphone-tracker.net' and we will manually send you a code.")
.setNeutralButton("OK", null).show();
}

Categories