Getting Twitter auth token with Volley POST request - android

I'm trying to produce a proper request for Twitter Application-only authorization token using a Volley POST request, but I keep getting a Http 400 response (Bad Request).
This is what I tried :
URL
private static final String TWITTER_API_AUTH_URL = "https://api.twitter.com/oauth2/token";
Encoding the consumer key and the consumer secret
try {
byte[] data = (URLEncoder.encode(TWITTER_CONSUMER_KEY, "UTF-8") + ":" + URLEncoder.encode(TWITTER_CONSUMER_SECRET, "UTF-8")).getBytes("UTF-8");
mEncodedKeyAndSecret = Base64.encodeToString(data, Base64.DEFAULT);
} catch (UnsupportedEncodingException e) {
//handleError
}
Custom Volley StringRequest
private class TokenRequestWithAuthHeader extends StringRequest{
public TokenRequestWithAuthHeader (int method, String url, Response.Listener listener, Response.ErrorListener errorListener)
{
super(method, url, listener, errorListener);
}
#Override
public Map getHeaders() throws AuthFailureError {
Map headers = new HashMap();
headers.put("Content-Length", String.valueOf(getBody().length));
headers.put("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
headers.put("Authorization", "Basic " + mEncodedKeyAndSecret);
return headers;
}
#Override
public byte[] getBody() {
return ("grant_type=client_credentials").getBytes();
}
}
Sending Request
tokenRequest = new TokenRequestWithAuthHeader
(Request.Method.POST, TWITTER_API_AUTH_URL, mCallback.getTokenResponseListener(), mCallback);
requestQueue.add(tokenRequest);
Documentation about Application-Only authentication at dev.twitter.com
I also tried extending JsonObjectRequest and JsonRequest instead of StringRequest, same result.
Can someone help identify what is the problem with the request ?

I have just tested with the credential you've provided in comments. It's working with the following logcat output (I truncated real access token's content)
I/onResponse: {"access_token":"AAAAAAAAAAAAAAAAAAAAAIwbjgAAAAAAGVMKCDU9taD0ke3sStAyA2WKszs%3DA4nfnpLTF31YuE.............JFtKjrTQC1K","token_type":"bearer"}
My code:
final RequestQueue queue = Volley.newRequestQueue(this);
final String url = "https://api.twitter.com/oauth2/token";
final String requestBody = "grant_type=client_credentials";
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, requestBody, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.i("onResponse", response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("onErrorResponse", error.toString());
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
// Basic Authentication
//String auth = "Basic " + Base64.encodeToString(CONSUMER_KEY_AND_SECRET.getBytes(), Base64.NO_WRAP);
String auth = "Basic cjMzZXVWeG5ZSDN3NjJ1RUdhV1NtcDAzYzpDa0h5Q3N1ZXF5ZXVobTExWURnTmpKMUZWRFN6OEk5TDFXWXJVUTFQWTNPZTcxcWlGdQ==";
headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
headers.put("Authorization", auth);
return headers;
}
};
queue.add(jsonObjectRequest);

private void fetchAccessTokens() {
final String requestBody = "grant_type=client_credentials";
JsonObjectRequest req1 = new JsonObjectRequest(Request.Method.POST,
TwitterTokenURL,
null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.i("Response: ", response.toString());
fetchTweets(response.toString());
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
// URL encode the consumer key and secret
String urlApiKey = null;
String urlApiSecret = null;
try {
urlApiKey = URLEncoder.encode(CONSUMER_KEY, "UTF-8");
urlApiSecret = URLEncoder.encode(CONSUMER_SECRET, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// Concatenate the encoded consumer key, a colon character, and the
// encoded consumer secret
String credentials = urlApiKey + ":" + urlApiSecret;
String auth = "Basic "
+ Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
headers.put("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
headers.put("Authorization", auth);
return headers;
}
#Override
public byte[] getBody() {
return requestBody.getBytes();
}
};
AppController.getInstance().addToRequestQueue(req1, tag_json_arry);
}

Related

Error Code 400 when implementing POST Request in Volley, but not when implementing with OkHttp

Given below is the class which I use to send a POST Request when using OkHttp:
public class PostExample {
private static final MediaType JSON
= MediaType.parse("application/json;");
private OkHttpClient client = new OkHttpClient();
String post(String url, String json) throws IOException {
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}
String bowlingJson(String user, String password) {
String str = "{" +
"\"username\": \"" + user + "\", " +
"\"password\": \"" + password + "\"" +
"}";
System.out.println(str);
return str;
}
public static void main(String[] args) throws IOException {
PostExample example = new PostExample();
String json = example.bowlingJson(args[0], args[1]);
String response = example.post("http://192.168.43.123:8000/api/jwt-auth/", json);
System.out.println(args[0] + " " + args[1]);
System.out.println(response);
}
}
This works fine, it gives me a JSON object as a string in response.
And given below is the almost same thing when used with Volley, just the difference that it is giving me a 400 Error
public class PostAssistant {
private Context context;
private RequestQueue queue;
public PostAssistant(Context context) {
this.context = context;
queue = Volley.newRequestQueue(context);
}
private void post(String url, final String user , final String password) throws IOException {
StringRequest postRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>()
{
#Override
public void onResponse(String response) {
// response
Log.d("Response", response);
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
// error
Log.d("Error.Response", "");
}
}
)
{
#Override
protected Map<String, String> getParams()
{
Map<String, String> params = new HashMap<>();
params.put("username", user);
params.put("password", password);
return params;
}
#Override
public String getBodyContentType()
{
return "application/json";
}
};
queue.add(postRequest);
}
private void connect(String user, String password) throws IOException {
post(Constants.loginUrl , user , password);
}
public void connect(String[] args) throws IOException {
connect(args[0] , args[1]);
}
}
This is the error as shown in the logcat:
E/Volley: [5322] BasicNetwork.performRequest: Unexpected response code 400 for http://192.168.43.123:8000/api/jwt-auth/
I fixed it by changing the getBodyContentType() to getHeaders()
#Override
public Map<String , String> getHeaders()
{
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/json");
return params;
}

How to use POST request in android Volley library with params and header?

I am trying to learn Volley library for posting data into webservices. I need to implement user registration form, following is the image of postman with parameters and header...
now problem is, i am getting below error
com.android.volley.ServerError
this is my code for volley post method.
public void postNewComment(){
try {
RequestQueue requestQueue = Volley.newRequestQueue(this);
String URL = "http://myurl/api/users";
JSONObject jsonBody = new JSONObject();
jsonBody.put("email", "test1#gmail.com");
jsonBody.put("user_type", "C");
jsonBody.put("company_id", "0");
jsonBody.put("status", "A");
jsonBody.put("password", "123456");
final String requestBody = jsonBody.toString();
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.i("VOLLEY", response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
Log.e("VOLLEY", error.toString());
}
}) {
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
final Map<String, String> headers = new HashMap<>();
headers.put("Authorization", "Basic " + "My_auth_key");
headers.put("Content-Type", "application/json");
return headers;
}
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String responseString = "";
if (response != null) {
responseString = String.valueOf(response.statusCode);
// can get more details such as response.headers
}
return Response.success(responseString, HttpHeaderParser.parseCacheHeaders(response));
}
};
requestQueue.add(stringRequest);
} catch (JSONException e) {
e.printStackTrace();
}
}
please suggest where am i getting wrong. URL is working correct with postman, also as you can see i need to set 2 headers. I also tried this Url post method with AsyncTask and its working good. Now i need to implement this using volley library. kindly suggest. thank you.
this is my logcat error:
E/Volley: [81910] BasicNetwork.performRequest: Unexpected response code 405 for "Myurl"
**Try this one **
private void sendWorkPostRequest() {
try {
String URL = "";
JSONObject jsonBody = new JSONObject();
jsonBody.put("email", "abc#abc.com");
jsonBody.put("password", "");
jsonBody.put("user_type", "");
jsonBody.put("company_id", "");
jsonBody.put("status", "");
JsonObjectRequest jsonOblect = new JsonObjectRequest(Request.Method.POST, URL, jsonBody, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Toast.makeText(getApplicationContext(), "Response: " + response.toString(), Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
onBackPressed();
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
final Map<String, String> headers = new HashMap<>();
headers.put("Authorization", "Basic " + "c2FnYXJAa2FydHBheS5jb206cnMwM2UxQUp5RnQzNkQ5NDBxbjNmUDgzNVE3STAyNzI=");//put your token here
return headers;
}
};
VolleyApplication.getInstance().addToRequestQueue(jsonOblect);
} catch (JSONException e) {
e.printStackTrace();
}
// Toast.makeText(getApplicationContext(), "done", Toast.LENGTH_LONG).show();
}
}
I have an alternative answer that works pretty well for Android Volley+ library by dworks and Google: See HERE

Volley return 403 error

From two days i am trying to solve this issue but still i have no any result,why each and every time volley returning me 403 error. where i m wrong? i am using postman to check same webservice, it returns success result. But same thing when i am using in Android via volley or httpurlconnection getting 403 error.kindly help me to find my error.
This is my code which i have tried:
StringRequest jsonObjectRequest = new StringRequest(Request.Method.POST, Constant.posturl, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
String result=response;
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
NetworkResponse response = error.networkResponse;
int status = response.statusCode;
}
}) {
#Override
public Map<String, String> getHeaders() {
try {
headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json");
String credentials = Constant.USERNAME + ":" + Constant.PASSWORD;
String auth = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.DEFAULT);
headers.put("Authorization", auth);
return headers;
} catch (Exception e) {
e.printStackTrace();
return headers;
}
}
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("title", heading_edit_text.getText().toString());
params.put("content", body_edit_text.getText().toString());
params.put("Slug", heading_edit_text.getText().toString());
params.put("date", currentDate);
return params;
}
};
jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(50000, 3, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
requestQueue.add(jsonObjectRequest);
Volley does provide a proper request for this which is called JsonObjectRequest.
String webAddress = "url here";
RequestQueue queue = Volley.newRequestQueue(this); // singletone here
JSONObject object = new JSONObject();
try {
object.put("title", heading_edit_text.getText().toString());
object.put("content", body_edit_text.getText().toString());
object.put("Slug", heading_edit_text.getText().toString());
object.put("date", currentDate);
} catch (JSONException e) {
}
JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, webAddress,object, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject object) {
Log.d("RESPONSE", object.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Log.d("RESPONSE", "That didn't work!");
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> header = new HashMap<>();
// content type is not needed here
header.put("Authorization", "value here");
return header;
}
};
queue.add(request);
Change the "Content-Type" of your headers to "application/form-data"
ie,
headers.put("Content-Type", "application/form-data");
I was also face this issue in news api. But when I use Retrfit its work like a charm.

Volley JsonObjectRequest with Basic Auth headers didn't work

I'm trying to send username and password as basic authorization with JsonObjectRequest. I've tried to Override getHeaders() method but it didn't work. Here is my code:
public class NewPostRequest extends JsonObjectRequest {
public NewPostRequest(JSONObject requestBody) {
super(Method.POST, APIConstants.CREATE_POST_URL, requestBody, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
long postId = response.getLong("id");
NewPostResponse newPostResponse = new NewPostResponse(postId);
EventBus.getDefault().post(newPostResponse);
} catch (JSONException e) {
e.printStackTrace();
EventBus.getDefault().post(new NewPostResponse(-1));
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
EventBus.getDefault().post(new NewPostResponse(-1));
}
});
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
String credentials = "****:***********************";
String auth = "Basic "
+ Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
headers.put("Content-Type", "application/json; charset=utf-8");
headers.put("Authorization", auth);
return headers;
}
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
JSONObject jsonObject = null;
try {
String data = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
jsonObject = new JSONObject(data);
} catch (UnsupportedEncodingException | JSONException e) {
e.printStackTrace();
}
return Response.success(jsonObject, HttpHeaderParser.parseCacheHeaders(response));
}
}
Error when i used Base64.NO_WRAP:
com.android.volley.AuthFailureError
And when i used Base64.DEFAULT:
java.lang.IllegalArgumentException: Unexpected char 0x0a at 46 in header value: Basic *************************
Note: This web service is working on Google Postman tool.
Check my answer its working fine for me.
Check this one

Android Volley JsonObjectRequest not send params

I'm trying to send a JsonObjectRequest to my server with some params, but seems like params doesn't arrive at the server. Before to post on SO I try all kind of suggestion found in google but no one works fine..
This is the code of my JsonObjectRequest:
RequestQueue queue = MySingleVolley.getInstance(ctx).
getRequestQueue();
JsonObjectRequest jsObjRequest = new JsonObjectRequest(method,url,null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("REQUEST_JSON_TO_SERVER", "Success: " + response.toString());
}
},new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("REQUEST_JSON_TO_SERVER", "Error: " + error);
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json");
return headers;
}
#Override
protected Map<String, String> getParams() {
return params;
}
};
MySingleVolley.getInstance(ctx).addToRequestQueue(jsObjRequest);
And these are my param and others:
String url = "url";
//create the hashMap of parameters
database_zappapp db = new database_zappapp(getApplicationContext());
db.open();
HashMap<String, String> params = new HashMap<>();
params.put("action","myAction");
params.put("nomeutente", db.getUsernameLogged());
params.put("token", token);
db.close();
//Send the request to the server
Global.RequestJsonToServer(getApplicationContext(), url, Request.Method.POST, params);
Thanks in advance for the help!
Edit 2
I've changed my params in this creating a string jsonBody:
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("action","gcmUserRegister");
jsonObject.put("nomeutente",db.getUsernameLogged());
jsonObject.put("token",token);
}catch(JSONException e){
e.printStackTrace();
}
String requestBody = jsonObject.toString();
db.close();
and my request like this with getBody():
JsonObjectRequest jsObjRequest = new JsonObjectRequest(method,url,null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("REQUEST_JSON_TO_SERVER", "Success: " + response.toString());
}
},new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("REQUEST_JSON_TO_SERVER", "Error: " + error);
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");
return headers;
}
#Override
public byte[] getBody() {
try {
return requestBody == null ? null : requestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s",
requestBody, "utf-8");
return null;
}
}
};
But already didn't work! =(
Postman screen:
No user found means that it enter in the if statement and so it works.. with android i receive "result": "null"
The postman screen with app/json:
I've found the solution!
The problem was in the server not in the client, I was getting the data using POST but from the client I was sending a json object so my new php is:
$data = json_decode(file_get_contents('php://input'), true);
//echo "Action: ".$action;
//Registrazione del token
if($data['action'] == "gcmUserRegister"){
......
Thanks al lot to BKS!!!
Change this part of your code:
`JsonObjectRequest jsObjRequest = new JsonObjectRequest(method,url,null ...`
To this:
`JsonObjectRequest jsObjRequest = new JsonObjectRequest(method,url,yourparams..`
Reason: if you are using the default Volley constructors thats the way to send params to Server.

Categories

Resources