英文:
OAuth 1.0 "Could not authenticate you."
问题
public String extendedtweet(String token, String secret,String id) throws IOException{
String url = "https://api.twitter.com/1.1/statuses/lookup.json";
headercreator hc = new headercreator(outhconsumerkey, consumersecret, token, secret);
Map<String,String> requestparams = new HashMap<String, String>();
Log.e("id", id);
requestparams.put("id", id);
// Add the "tweet_mode=extended" parameter
requestparams.put("tweet_mode", "extended");
String header = hc.generateHeader("GET", url, requestparams);
Log.e("header", header);
Response response = request(url, "", "GET", "Authorization", header);
String jsonData = response.body().string();
JsonObject js = new Gson().fromJson(jsonData, JsonObject.class);
return js.get("full_text").getAsString();
}
The issue you're facing seems to be with authentication. The error message you're receiving, { "errors":[{"code":32,"message":"Could not authenticate you."}]}
, indicates a problem with the authentication process. Make sure that your OAuth credentials (consumer key, consumer secret, token, and token secret) are correct and properly configured. Double-check that you're using the correct keys and secrets from your Twitter Developer account.
Additionally, ensure that your system's time is synchronized correctly, as OAuth 1.0a relies on timestamp and nonce values. If the timestamp is significantly different from Twitter's servers, it can cause authentication failures.
Since the problem seems to be authentication-related, please review your OAuth credentials and ensure that they are accurately implemented in your code.
英文:
Hı first of all this is a twitter auth. I can login, I can get the timeline etc etc. I can get those things because they dont want an extra paramaters. But now ı want to add "tweet_mode=extended" paramaters to that.
public String extendedtweet(String token, String secret,String id) throws IOException{
String url="https://api.twitter.com/1.1/statuses/lookup.json";
headercreator hc=new headercreator(outhconsumerkey,consumersecret,token,secret);
Map<String,String> requestparams = new HashMap<String, String>();
Log.e("id",id);
requestparams.put("id",id);
String header=hc.generateHeader("GET",url,requestparams);
Log.e("header",header);
Response response =request(url,"","GET","Authorization",header);
String jsonData=response.body().string();
JsonObject js=new Gson().fromJson(jsonData, JsonObject.class);
return js.get("full_text").getAsString();
}
When ı Delete the
requestparams.put("id",id);
Line at there it says id paramaters is missing.That is Nice because that shows me the problem is at the Headercreator class which is here :
package com.example.twittertestvol1;
import android.os.Build;
import android.util.Log;
import androidx.annotation.RequiresApi;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
/**
* Class to generate Oauth 1.0a header for Twitter
*
*/
@RequiresApi(api = Build.VERSION_CODES.N)
public class headercreator {
private String consumerKey;
private String consumerSecret;
private String signatureMethod;
private String token;
private String tokenSecret;
private String version;
public headercreator(String consumerKey, String consumerSecret, String token, String tokenSecret) {
this.consumerKey = consumerKey;
this.consumerSecret = consumerSecret;
this.token = token;
this.tokenSecret = tokenSecret;
this.signatureMethod = "HMAC-SHA1";
this.version = "1.0";
}
private static final String oauth_consumer_key = "oauth_consumer_key";
private static final String oauth_token = "oauth_token";
private static final String oauth_signature_method = "oauth_signature_method";
private static final String oauth_timestamp = "oauth_timestamp";
private static final String oauth_nonce = "oauth_nonce";
private static final String oauth_version = "oauth_version";
private static final String oauth_signature = "oauth_signature";
private static final String HMAC_SHA1 = "HmacSHA1";
/**
* Generates oAuth 1.0a header which can be pass as Authorization header
*
* @param httpMethod
* @param url
* @param requestParams
* @return
*/
public String generateHeader(String httpMethod, String url, Map<String, String> requestParams) {
StringBuilder base = new StringBuilder();
String nonce = getNonce();
String timestamp = getTimestamp();
String baseSignatureString = generateSignatureBaseString(httpMethod, url, requestParams, nonce, timestamp);
String signature = encryptUsingHmacSHA1(baseSignatureString);
base.append("OAuth ");
append(base, oauth_consumer_key, consumerKey);
append(base, oauth_token, token);
append(base, oauth_signature_method, signatureMethod);
append(base, oauth_timestamp, timestamp);
append(base, oauth_nonce, nonce);
append(base, oauth_version, version);
append(base, oauth_signature, signature);
base.deleteCharAt(base.length() - 1);
return base.toString();
}
/**
* Generate base string to generate the oauth_signature
*
* @param httpMethod
* @param url
* @param requestParams
* @return
*/
private String generateSignatureBaseString(String httpMethod, String url, Map<String, String> requestParams, String nonce, String timestamp) {
Map<String, String> params = new HashMap<>();
if (requestParams!=null)
{
requestParams.entrySet().forEach(entry -> {
put(params, entry.getKey(), entry.getValue());
});
}
put(params, oauth_consumer_key, consumerKey);
put(params, oauth_nonce, nonce);
put(params, oauth_signature_method, signatureMethod);
put(params, oauth_timestamp, timestamp);
put(params, oauth_token, token);
put(params, oauth_version, version);
Map<String, String> sortedParams = params.entrySet().stream().sorted(Map.Entry.comparingByKey())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
StringBuilder base = new StringBuilder();
sortedParams.entrySet().forEach(entry -> {
base.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
});
base.deleteCharAt(base.length() - 1);
String baseString = httpMethod.toUpperCase() + "&" + encode(url) + "&" + encode(base.toString());
return baseString;
}
@RequiresApi(api = Build.VERSION_CODES.O)
private String encryptUsingHmacSHA1(String input) {
String secret = new StringBuilder().append(encode(consumerSecret)).append("&").append(encode(tokenSecret)).toString();
byte[] keyBytes = secret.getBytes(StandardCharsets.UTF_8);
SecretKey key = new SecretKeySpec(keyBytes, HMAC_SHA1);
Mac mac;
try {
mac = Mac.getInstance(HMAC_SHA1);
mac.init(key);
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
e.printStackTrace();
return null;
}
byte[] signatureBytes = mac.doFinal(input.getBytes(StandardCharsets.UTF_8));
return new String(Base64.getEncoder().encode(signatureBytes));
}
/**
* Percentage encode String as per RFC 3986, Section 2.1
*
* @param value
* @return
*/
private 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;
}
}
return sb.toString();
}
private void put(Map<String, String> map, String key, String value) {
map.put(encode(key), encode(value));
}
private void append(StringBuilder builder, String key, String value) {
builder.append(encode(key)).append("=\"").append(encode(value)).append("\",");
}
private String getNonce() {
int leftLimit = 48; // numeral '0'
int rightLimit = 122; // letter 'z'
int targetStringLength = 10;
Random random = new Random();
String generatedString = random.ints(leftLimit, rightLimit + 1).filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97)).limit(targetStringLength)
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();
return generatedString;
}
private String getTimestamp() {
return Math.round((new Date()).getTime() / 1000.0) + "";
}
}
Nowı wonder if someone shows me where is the problem why ı cant solve that. And that is the error code and error for that
> {"errors":[{"code":32,"message":"Could not authenticate you."}]}
Here is thre request function
private Response request(String url, String bodys, String type, String Headername, String Header) throws IOException {
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("text/plain");
RequestBody body = RequestBody.create(mediaType,bodys);
Request request;
if (!Headername.equals(""))
{
if (type.equals("GET"))
{
request = new Request.Builder()
.url(url)
.method(type,null)
.addHeader(Headername,Header)
.build();
}
else{
request = new Request.Builder()
.url(url)
.method(type, body)
.addHeader(Headername,Header)
.build();
}
}
else {
request = new Request.Builder()
.url(url)
.method(type, body)
.build();
}
return client.newCall(request).execute();
}
答案1
得分: 1
问题出在Response response =request(url, "", "GET", "Authorization", header);
。
在调用服务时,您需要传递请求参数,但是在调用request()
方法时没有传递id
或任何其他参数。对我来说,以下代码有效:
public void getTweet() {
Map<String, String> requestParams = new HashMap<>();
String id = "1263213348000325633";
// Pass all request params for header generation
requestParams.put("id", id);
requestParams.put("tweet_mode", "extended");
String url = "https://api.twitter.com/1.1/statuses/lookup.json";
String header = generator.generateHeader(HttpMethod.GET.name(), url, requestParams);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", header);
HttpEntity<String> httpEntity = new HttpEntity<String>("body", headers);
// Pass all request params in the request
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url)
.queryParam("id", id)
.queryParam("tweet_mode", "extended");
ResponseEntity<String> response = restTemplate.exchange(builder.toUriString(), HttpMethod.GET, httpEntity, String.class);
String responseBody = response.getBody();
assertNotNull(responseBody);
System.out.println(responseBody);
}
可在此处找到可运行的代码链接,作为单元测试。
英文:
Issue is at Response response =request(url,"","GET","Authorization",header);
.
You need to pass in the request params when calling the service but you are not passing the id
or any other param when calling the request()
method. For me following code works:
public void getTweet() {
Map<String, String> requestParams = new HashMap<>();
String id = "1263213348000325633";
// Pass all request params for header generation
requestParams.put("id", id);
requestParams.put("tweet_mode", "extended");
String url = "https://api.twitter.com/1.1/statuses/lookup.json";
String header = generator.generateHeader(HttpMethod.GET.name(), url, requestParams);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", header);
HttpEntity<String> httpEntity = new HttpEntity<String>("body", headers);
// Pass all request params in the request
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url)
.queryParam("id", id)
.queryParam("tweet_mode", "extended");
ResponseEntity<String> response = restTemplate.exchange(builder.toUriString(), HttpMethod.GET, httpEntity, String.class);
String responseBody = response.getBody();
assertNotNull(responseBody);
System.out.println(responseBody);
}
Working code available here as a junit.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论