【发布时间】:2020-10-02 12:25:23
【问题描述】:
我想使用 twitter API https://api.twitter.com/1.1/statuses/user_timeline.json 创建一个 Oauth。 我已经收集了一些 Java 代码,并且能够在 twitter 示例 Twitter Oath Example
中重现签名我的问题。
我的 URL 还包含一些额外的参数,我不确定如何在 %encoded 字符串中表示这些参数。
这是我目前拥有的。
Method: "GET"
URL: "https://api.twitter.com/1.1/statuses/user_timeline.json
Parameters: "screen_name=user handle"
CONSUMER_API_KEY = "oauth_consumer_key=gdprVZGNotRealKeyZRGMUfP";
OAUTH_NONCE = "oauth_nonce=u4cknC6Lfea";
HMACSHA1 ="oauth_signature_method=HMAC-SHA1";
OAUTH_TIMESTAMP = "oauth_timestamp=1591889894";
ACCESS_TOKEN = "oauth_token=63345074-vNvsSSlMsMmNotRealKeytGR040GD9";
oauth_version ="oauth_version=1.0";
public class MainActivity extends AppCompatActivity {
private ArrayList<MyTweet> tweets = new ArrayList<MyTweet>();
private TextView post_reponse_text;
private MyTweetsAdapter Adapter;
Twitter twitter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button post_request_button = findViewById(R.id.test);
post_reponse_text = findViewById(R.id.get_response_data);
post_request_button.setOnClickListener(new View.OnClickListener() {
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onClick(View v) {
postRequest();
String url = "https://api.twitter.com/1.1/statuses/user_timeline.json";
test t1 = new test();
//t1.concatURL(url,"GET");
//String percented = t1.encode(url);
String percentURL1 = t1.encode(url);
Log.v("String encoded with ent",percentURL1);
Log.v("Concat:",t1.StringConcat());
String fin = t1.concatURL(percentURL1,"GET") + t1.encode(t1.StringConcat());
Log.v("FinishedString:",fin);
Log.v("Sig:",t1.generateSignature(fin, "CONSUMERSECREATrFMeKkS", "TOKENSECREATvqWFWzxEZtGdc"));
}
});
}
private void postRequest() {
RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
String url = "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=user handle";
final StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.e("HttpClient", "success! response: " + response.toString());
try {
// post_reponse_text.setText("Post Data : " + response);
post_reponse_text.setText("Twitter Feed");
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject session = jsonArray.getJSONObject(i);
MyTweet tweet = new MyTweet("might need to remove", "this also");
tweet.content = session.getString("text");
tweet.author = session.getString("id_str");
tweets.add(tweet);
}
/*Send to Adapter*/
RecyclerView recyclerView = findViewById(R.id.my_recycler_view);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
Adapter = new MyTweetsAdapter(tweets);
recyclerView.setAdapter(Adapter);
Adapter.setOnItemClickListener(new MyTweetsAdapter.OnItemClickListener() {
@Override
public void onItemClick(int position) {
}
});
} catch (Exception e) {
e.printStackTrace();
Log.v("Error:", "Error Creating JSON object");
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
Log.e("HttpClient", "error: " + error.toString());
post_reponse_text.setText("Failed to find Twitter feed");
}
})
{
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
//Generated from postman and added manually
params.put("Authorization", "OAuth oauth_consumer_key=\"notrealkeyZRGMUfP\",oauth_token=\"63139074-vNvsSSnotrealkey\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1592143976\",oauth_nonce=\"i5Ha2524SuC\",oauth_signature=\"DFf7rD9enXp1pIxsCkf99VC4rSE%3D\"");
return params;
}
};
queue.add(stringRequest);
}
}
公开课测试{
//http://optimumbrew.com/blog/2015/03/oauth/how-to-generate-oauth-signature-for-twitter-in-core-java
//used to % encode string values
@RequiresApi(api = Build.VERSION_CODES.O)
public String encode(String value) {
String encoded = "";
try {
encoded = URLEncoder.encode(value, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
String sb = "";
char focus;
for (int i = 0; i < encoded.length(); i++) {
focus = encoded.charAt(i);
if (focus == '*') {
sb += "%2A";
} else if (focus == '+') {
sb += "%20";
} else if (focus == '%' && i + 1 < encoded.length()
&& encoded.charAt(i + 1) == '7' && encoded.charAt(i + 2) == 'E') {
sb += '~';
i += 2;
} else {
sb += focus;
}
}
Log.v("String Encoded:", sb);
return sb;
}
//passes the string with consumer secret & token to generate a signature.
//I will send this signature in the header requests
@RequiresApi(api = Build.VERSION_CODES.O)
public String generateSignature(String signatueBaseStr, String oAuthConsumerSecret, String oAuthTokenSecret) {
byte[] byteHMAC = null;
try {
Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec spec;
if (null == oAuthTokenSecret) {
String signingKey = encode(oAuthConsumerSecret) + '&';
spec = new SecretKeySpec(signingKey.getBytes(), "HmacSHA1");
} else {
String signingKey = encode(oAuthConsumerSecret) + '&' + encode(oAuthTokenSecret);
spec = new SecretKeySpec(signingKey.getBytes(), "HmacSHA1");
}
mac.init(spec);
byteHMAC = mac.doFinal(signatueBaseStr.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
return twitter4j.BASE64Encoder.encode(byteHMAC);
// return new twitter4j.BASE64Encoder().encode(byteHMAC);
}
public String concatURL(String url, String method) {
String contact = method + "&" + url+"&";
return contact;
}
@RequiresApi(api = Build.VERSION_CODES.O)
public String StringConcat() {
String CONSUMER_API_KEY = "oauth_consumer_key=gdnotrealkeyRGMUfP";
String OAUTH_NONCE = "oauth_nonce=i5Ha2524SuC";
String HMACSHA1 ="oauth_signature_method=HMAC-SHA1";
String OAUTH_TIMESTAMP = "oauth_timestamp=1592143976";
String ACCESS_TOKEN = "oauth_token=63139074-vNvnotrealkeygJn8VtGR040GD9";
String oauth_version ="oauth_version=1.0";
String screen_name = "screen_name=user handle";
/*
oauth_consumer_key=\"gdprVZGkHT7mOfALr8ZRGMUfP\",
oauth_nonce=\"u4cknC6Lfea\",
oauth_signature_method=\"HMAC-SHA1\",
oauth_timestamp=\"1591889894\",
oauth_token=\"63139074-vNvsSSlMsMmosQwJ2EWVmHvGzAlgJn8VtGR040GD9\"
*/
String concat = CONSUMER_API_KEY+ "&" +OAUTH_NONCE+ "&" +HMACSHA1+ "&" +OAUTH_TIMESTAMP+ "&" +ACCESS_TOKEN+ "&" +oauth_version+ "&"+screen_name;
//String concat = CONSUMER_API_KEY+ "&" +OAUTH_NONCE+ "&" +HMACSHA1+ "&" +OAUTH_TIMESTAMP+ "&" +ACCESS_TOKEN+ "&" +oauth_version;
return concat;
}
}
Combining to make
GET&https%3A%2F%2Fapi.twitter.com%2F1.1%2Fstatuses%2Fuser_timeline.json&oauth_consumer_key%3DgdprVZGNotRealKeyZRGMUfP%26oauth_nonce%3Du4cknC6Lfea%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1591889894%26oauth_token%3D63345074-vNvsSSlMsMmNotRealKeytGR040GD9%26oauth_version%3D1.0%26screen_name%3Duser%20handle
Using postman I can get instances of successful auths and can see the created signature of those auths. Using the timestamps and nonces from postman I am trying to validate I can create the same signature as postman. So far I'm unsuccessful and I'm assuming its something to do with how i put the string together
【问题讨论】:
标签: java twitter oauth postman twitter-oauth