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);