Last Updated
Viewed 18 Times
        

I am trying to connect to the twitter API using OAuth2 method toget the bearer token. I am using an AsyncTask making the call to Twitter. My request seems to be accepted and return an error code 200, but when I try to read the content which is supposed to contain the token that I want, but the format is odd, as well as the content-length of the response.

I am building it according to https://developer.twitter.com/en/docs/basics/authentication/overview/application-only

Here is the AsyncTask I am using to make the request:

private class RequestBearerTockenTask extends AsyncTask<String, Integer, String> {
    @Override
    protected String doInBackground(String... string) {

        // On récupère les keys passées en paramètre
        String consumerKey = string[0];
        String secretKey = string[1];

        // On encode en base64 le bearerToken en accord avec la doc twitter
        String base64encodedBearerToken = Base64.encodeToString((consumerKey + ":" + secretKey).getBytes(), Base64.NO_WRAP);

        // Variables locales de la fonction
        String bearerTocken = "";
        URL url = null;
        HttpURLConnection urlConnection = null;

        try {
            // On formate la requete HTTP
            url = new URL("https://api.twitter.com/oauth2/token");
            urlConnection = (HttpURLConnection) url.openConnection();

            urlConnection.setRequestMethod("POST");
            urlConnection.setRequestProperty("Host", "api.twitter.com");
            urlConnection.setRequestProperty("User-Agent", " My Twitter App v1.0.23");
            urlConnection.setRequestProperty("Authorization", "Basic " + base64encodedBearerToken);
            urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
            urlConnection.setRequestProperty("Content-Length", "29");
            urlConnection.setRequestProperty("Accept-Encoding", "gzip");

            String requestBody =  "grant_type=client_credentials";
            byte[] outputInBytes = requestBody.getBytes("UTF-8");
            OutputStream os = urlConnection.getOutputStream();
            os.write( outputInBytes );
            os.close();

            // On lit l'entete de la reponse
            int responseCode = urlConnection.getResponseCode();

            switch (responseCode) {
                case 200:
                case 201:

                    BufferedReader rd = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
                    String line;
                    while ((line = rd.readLine()) != null) {
                        bearerTocken += line;
                    }
                    break;
                default:
                    bearerTocken = "";
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bearerTocken;
    }
}

The bearerToken at the end is like:

����������������V*��N͋/�,HU�RJJM,J-R�QJLNN-.�K�����/�rW03��5��+81��$���=?[��)�ɱ���B�إа�2�)+����$�2�� ����?���?7�;�0�2�995=�-=/$$�"�30T�����������9�뇛������

with a content length of 149 instead of 140 according to the documentation.

Do you have any clue why I am getting such a response?

I need to implement an OAuth login in my Android application using the Twitter API. I found a great project on GitHub (spring-android-samples) with a very good example, but I have a problem with respect to the parameter "Callback URL".

When I submit my login and password, my android application opens a browser instance (with callback URL) rather than processing the response in the background:

enter image description here

Has anyone had to implement something similar and could help me please? Thank you!

I am trying to fetch the application only bearer token by using my consumer key and consumer secret following this. This is my implementation:

public class OAuthApplicationOnlyBearerTokenFetchTask extends AsyncTask<String, Void, String> {
    private static Logger logger =
            Logger.getLogger(OAuthApplicationOnlyBearerTokenFetchTask.class.getName());

    final static String URL_TWITTER_OAUTH2_TOKEN = "https://api.twitter.com/oauth2/token";
    final static String USER_AGENT = "TwitterMotion User Agent";

    protected String mApplicationOnlyBearerToken;

    @Override
    protected String doInBackground(String... tokens) {
        String consumerKey = tokens[0];
        String consumerSecret = tokens[0];
        String encodedCredentials = encodeKeysFrom(consumerKey, consumerSecret);

        HttpURLConnection urlConnection = null;
        try {
            URL url = new URL(URL_TWITTER_OAUTH2_TOKEN);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setDoOutput(true);
            urlConnection.setDoInput(true);
            urlConnection.setRequestMethod("POST");
            urlConnection.setRequestProperty("Host", "api.twitter.com");
            urlConnection.setRequestProperty("User-Agent", USER_AGENT);
            urlConnection.setRequestProperty("Authorization", "Basic " + encodedCredentials);
            urlConnection.setRequestProperty("Content-Type",
                    "application/x-www-form-urlencoded;charset=UTF-8");
            urlConnection.setRequestProperty("Content-Length", "29");
            urlConnection.setUseCaches(false);

            writeRequest(urlConnection, "grant_type=client_credentials");
            String jsonResponse = readResponse(urlConnection);
            logger.log(INFO, "jsonResponse of the bearer oauth request: ", jsonResponse);

            if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_FORBIDDEN) {
                logger.log(Level.SEVERE, "HTTP 403 (Forbidden) returned from Twitter API call for bearer token. " +
                        "Check values of Consumer Key and Consumer Secret in tokens.properties");
                throw new RejectedAuthorizationException(urlConnection.getResponseCode(), "HTTP 403 (Forbidden) returned attempting to get Twitter API bearer token");
            }

            JSONObject jsonResponseObject = new JSONObject(jsonResponse);

            if (jsonResponseObject != null) {
                mApplicationOnlyBearerToken = (String) jsonResponseObject.get("access_token");
            } else {
                // TODO
            }
            return mApplicationOnlyBearerToken;
        } catch (Exception ex) {
            logger.log(Level.SEVERE, "", ex);
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
        }
        return null;
    }

    @Override
    protected void onPostExecute(String applicationOnlyBearerToken) {
        this.mApplicationOnlyBearerToken = applicationOnlyBearerToken;
    }

    public String getApplicationOnlyBearerToken() {
        return mApplicationOnlyBearerToken;
    }

    private String encodeKeysFrom(String consumerKey, String consumerSecret) {
        try {
            String encodedConsumerKey = URLEncoder.encode(consumerKey, "UTF-8");
            String encodedConsumerSecret = URLEncoder.encode(consumerSecret, "UTF-8");

            String combinedEncodedKey = encodedConsumerKey + ":" + encodedConsumerSecret;
            byte[] encodedBytes = Base64.encode(combinedEncodedKey.getBytes(), Base64.NO_WRAP);
            return new String(encodedBytes);
        }
        catch (UnsupportedEncodingException e) {
            // TODO
            return null;
        }
    }

    private boolean writeRequest(HttpURLConnection connection, String requestBody)
            throws IOException {
        BufferedWriter bufferedWriter = null;
        try {
            bufferedWriter = new BufferedWriter(
                    new OutputStreamWriter(connection.getOutputStream()));
            bufferedWriter.write(requestBody);
            bufferedWriter.flush();

            return true;
        }
        catch (IOException ex) {
            return false;
        }
        finally {
            if (bufferedWriter != null) {
                bufferedWriter.close();
            }
        }
    }


    private String readResponse(HttpURLConnection connection) throws IOException {
        BufferedReader bufferedReader = null;
        try {
            StringBuilder stringBuilder = new StringBuilder();
            bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line;
            while((line = bufferedReader.readLine()) != null) {
                stringBuilder.append(line + System.getProperty("line.separator"));
            }
            return stringBuilder.toString();
        }
        catch (IOException e) {
            return null;
        }
        finally {
            if (bufferedReader != null) {
                bufferedReader.close();
            }
        }
    }

}

But I am getting HTTP 403 Forbidden.

I also added permission on manifest file:

<uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

I can not understand what is the issue actually. Thanks in advance!

I'm using Twitter4j library to authorize user with OAuth for my application on Android. But I'm facing this exception when I try to get OAuth request token. I know there are bunch of topics about this (Twitter4J + Android: Authentication Challenge is Null Exception like this one) but none did fix my problem. Here is the simple code sample that explains my problem;

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  prefs = getSharedPreferences("twitterPrefs", MODE_PRIVATE);
  twitter = new TwitterFactory().getInstance();
  twitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
  LoginButton = (Button) findViewById(R.id.login_button);
}

I'm setting consumer key and also secret key, and I get well formed twitter object but when user clicks on the login button;

private void loginNewUser() {
    try {
        currentRequestToken = twitter.getOAuthRequestToken(CALLBACK_URL);

        setUpViews();
        WebView twitterSite = new WebView(this);
        twitterSite.loadUrl(currentRequestToken.getAuthenticationURL());

        setContentView(R.layout.authorization_view);

    } catch (TwitterException e) {
        Toast.makeText(this, "Twitter Login error, try again later", Toast.LENGTH_SHORT).show();
    }
}

I get exception because getOAuthRequestToken(CALLBACK_URL) equals null; received authentication challenge is null.

I'm sure that timestamp is true on device and also async task for request token didn't work.

Any help would be appreciated

Similar Question 6 (1 solutions) : Twitter OAuth callback does not seem to work in Android

cc