Search code examples
androidtwitteroauth-2.0android-volley

Getting Twitter auth token with Volley POST request


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 ?


Solution

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