Twitter 仅获取应用程序不记名令牌 HTTP 403 Forbidden

Twitter fetching application only bearer token HTTP 403 Forbidden

我正在尝试通过使用我的消费者密钥和消费者秘密来获取应用程序唯一的不记名令牌 this。这是我的实现:

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

}

但我得到 HTTP 403 Forbidden

我还添加了对清单文件的权限:

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

我不明白到底是什么问题。提前致谢!

没关系,我已经找到了 bug。

String consumerKey = tokens[0];
String consumerSecret = tokens[0];

应该是

String consumerSecret = tokens[1];