【问题标题】:Getting Twitter auth token with Volley POST request使用 Volley POST 请求获取 Twitter 身份验证令牌
【发布时间】:2016-04-04 14:52:30
【问题描述】:

我正在尝试使用 Volley POST 请求为仅限 Twitter 应用程序的授权令牌生成正确的请求,但我不断收到 Http 400 响应(错误请求)。

这是我尝试过的:

网址

private static final String TWITTER_API_AUTH_URL = "https://api.twitter.com/oauth2/token";

对消费者密钥和消费者秘密进行编码

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
}

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

发送请求

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

我还尝试扩展JsonObjectRequestJsonRequest 而不是StringRequest,结果相同。

有人可以帮助确定请求的问题吗?

【问题讨论】:

  • 您在使用Postman之类的工具时有没有收到成功的回复?
  • 我在 www.hurl.it 上生成了一个请求,其中包含我在 LogCat 中打印出来的编码基本身份验证标头,该标头是从我上面使用的相同代码生成的,使用相同的内容类型标头,并得到了预期 200 成功响应。我很困惑:)
  • 如果只是为了测试或学习,能否贴出 TWITTER_CONSUMER_KEY 和 TWITTER_CONSUMER_SECRET 或者编码的 Basic 身份验证标头以便我们检查?
  • 当然,这里是:基本 cjMzZXVWeG5ZSDN3NjJ1RUdhV1NtcDAzYzpDa0h5Q3N1ZXF5ZXVobTExWURnTmpKMUZWRFN6OEk5TDFXWXJVUTFQWTNPZTcxcWlGdQ==

标签: android twitter oauth-2.0 android-volley


【解决方案1】:

我刚刚使用您在 cmets 中提供的凭据进行了测试。它使用以下 logcat 输出(我截断了真实访问令牌的内容)

I/onResponse: {"access_token":"AAAAAAAAAAAAAAAAAAAAAIwbjgAAAAAAGVMKCDU9taD0ke3sStAyA2WKszs%3DA4nfnpLTF31YuE.............JFtKjrTQC1K","token_type":"bearer"}

我的代码:

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

【讨论】:

  • 谢谢,吃完我试试看!
  • 像魅力一样工作,再次感谢!仍然不确定我之前尝试的 JSONRequest 实现有什么问题,看起来非常相似。如果我能理解这一点,我会在这里发布我的发现:)
  • TokenRequestWithAuthHeader requestWithAuthHeader = new TokenRequestWithAuthHeader(1, url, new Response.Listener&lt;String&gt;(){ @Override public void onResponse(String response) { Log.i(LOG_TAG, response); } }, new Response.ErrorListener(){ @Override public void onErrorResponse(VolleyError error) { Log.e(LOG_TAG, error.toString()); } }); queue.add(requestWithAuthHeader); 也可以:)
  • 终于明白了:我的代码中有两个小错误,首先我在application/x-www-form-urlencoded之间缺少一个空格;和charset=UTF-8,其次我使用Base64.DEFAULT 在字符串中间添加一个空格(不知道为什么,我认为这只是LogCat 这样做是为了便于阅读),使用Base64.NO_WRAP 解决了这个问题......再次感谢您的帮助,祝您新年快乐!
  • 很高兴听到这个消息,也祝您和您的家人新年快乐 :)
【解决方案2】:
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);

    }

【讨论】:

  • 不要只是发布代码,您需要解释这如何回答 OP 提出的问题,也许是关于它是如何工作的,等等。
猜你喜欢
  • 2018-11-12
  • 1970-01-01
  • 1970-01-01
  • 2017-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多