Java 为Twitter API生成签名的正确方法是什么?
这是我的请求代码aa表示我的消费者密钥,bb是userAcessTokenSecret。为了安全起见,我更改了值。我不知道是因为游标参数还是编码和散列值和键的方式Java 为Twitter API生成签名的正确方法是什么?,java,api,twitter,encode,signature,Java,Api,Twitter,Encode,Signature,这是我的请求代码aa表示我的消费者密钥,bb是userAcessTokenSecret。为了安全起见,我更改了值。我不知道是因为游标参数还是编码和散列值和键的方式 public static void getLocationAndNameOfFollowers(String userAcessToken, String userAcessTokenSecret) throws IOException, InvalidKeyException, NoSuchAlgorithmException {
public static void getLocationAndNameOfFollowers(String userAcessToken, String userAcessTokenSecret) throws IOException, InvalidKeyException, NoSuchAlgorithmException {
userAcessTokenSecret = "bb";
String signingKey = GenerateSignature.oAuthSigningKey("aa", userAcessTokenSecret);
long ts = new Timestamp(System.currentTimeMillis()).getTime() / 1000;
String timeStamp = String.valueOf(ts);
String nonce = GenerateSignature.generateNonce("aa", timeStamp);
String baseString = GenerateSignature.oAuthBaseString("GET", "https://api.twitter.com/1.1/followers/list.json?",
"cursor-1", "fHkdJVy3x1fKE1Yop9qraJyCp", userAcessToken, timeStamp, nonce);
String oauth_signature = GenerateSignature.oAuthSignature(baseString, signingKey);
JSONObject response = Unirest.get("https://api.twitter.com/1.1/followers/list.json?cursor=-1")
.header("Content-Type", "application/x-www-form-urlencoded")
.header("Authorization", "OAuth oauth_consumer_key=\"consumer_key\"," +
"oauth_token=" + "\"" + userAcessToken +"\""+ "," +
"oauth_signature_method=" + "\"HMAC-SHA1\"," +
"oauth_timestamp=" + "\""+timeStamp + "\"" + "," +
"oauth_nonce=" + "\""+nonce + "\"" + "," +
"oauth_version=\"1.0\"," +
"oauth_signature=" + "\"" +oauth_signature + "\"")
.asJson().getBody().getObject();
下面的代码包含my helper函数
private static String percentEncoding(String originalString) {
String encodedString = Base64.getUrlEncoder().encodeToString(originalString.getBytes());
return encodedString;
}
public static String oAuthBaseString(String method, String url, String parameters, String key, String token, String timestamp, String nonce) {
System.out.println("generated sorted parameter string -> "+generateSortedParameterString(parameters, key, token, timeStamp , nonce));
String res = method + "&" + percentEncoding(url)
+ "&" + generateSortedParameterString(parameters, key, token, timeStamp , nonce);
System.out.println("oauth base string -> \n\n\n" + res);
return res;
}
public static String oAuthSignature(String baseString, String tokenSecret) throws NoSuchAlgorithmException, InvalidKeyException {
byte[] bytes = baseString.getBytes(StandardCharsets.UTF_8);
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(new SecretKeySpec(bytes, "HmacSHA1"));
byte[] res = mac.doFinal(tokenSecret.getBytes(StandardCharsets.UTF_8));
return percentEncoding(Base64.getEncoder().toString());
}
public static String oAuthSigningKey(String consumerSecret, String accessTokenSecret) {
return consumerSecret + "&" + accessTokenSecret;
}
public static String generateNonce(String consumerKey, String timeStamp) {
String nonce = Base64.getEncoder().encodeToString((consumerKey + ":" + timeStamp).getBytes());
return nonce;
}
public static String generateSortedParameterString(String parameter, String key, String token, String timeStamp, String nonce) {
Map<String, String> parameters = new LinkedHashMap<>();
parameters.put("oauth_consumer_key", key);
parameters.put("oauth_nonce", nonce);
parameters.put("oauth_signature_method", "HMAC-SHA1");
parameters.put("oauth_timestamp", timeStamp);
parameters.put("oauth_token", token);
parameters.put("oauth_version", "1.0");
System.out.println("parameter map is here -> "+parameters);
String parameterString = parameters.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.map(e -> percentEncoding(e.getKey()) + "=" + percentEncoding(e.getValue()))
.collect(Collectors.joining("&"));
return parameterString;
}
私有静态字符串百分比编码(字符串原始字符串){
字符串encodedString=Base64.getUrlEncoder().encodeToString(originalString.getBytes());
返回编码环;
}
公共静态字符串oAuthBaseString(字符串方法、字符串url、字符串参数、字符串键、字符串标记、字符串时间戳、字符串nonce){
System.out.println(“生成的排序参数字符串->”+生成的排序参数字符串(参数、键、令牌、时间戳、nonce));
字符串res=方法+“&”+百分比编码(url)
+“&”+generateSortedParameterString(参数、密钥、令牌、时间戳、nonce);
System.out.println(“oauth基本字符串->\n\n\n”+res);
返回res;
}
公共静态字符串oAuthSignature(字符串baseString、字符串tokenSecret)抛出NoSuchAlgorithmException、InvalidKeyException{
byte[]bytes=baseString.getBytes(StandardCharsets.UTF_8);
Mac Mac=Mac.getInstance(“HmacSHA1”);
init(新的SecretKeySpec(字节,“HmacSHA1”);
byte[]res=mac.doFinal(tokenSecret.getBytes(StandardCharsets.UTF_8));
返回percentEncoding(Base64.getEncoder().toString());
}
公共静态字符串oAuthSigningKey(字符串ConsumerCret、字符串accessTokenSecret){
返回ConsumerCret+“&”+accessTokenSecret;
}
公共静态字符串生成器(字符串使用者、字符串时间戳){
字符串nonce=Base64.getEncoder().encodeToString((consumerKey+“:”+timeStamp.getBytes());
返回当前值;
}
公共静态字符串generateSortedParameterString(字符串参数、字符串键、字符串标记、字符串时间戳、字符串nonce){
映射参数=新建LinkedHashMap();
参数put(“oauth_consumer_key”,key);
参数put(“oauth_nonce”,nonce);
参数put(“oauth_签名_方法”、“HMAC-SHA1”);
参数put(“oauth_timestamp”,timestamp);
参数put(“oauth_令牌”,令牌);
参数put(“oauth_版本”、“1.0”);
System.out.println(“这里是参数映射->”+参数);
String parameterString=parameters.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.map(e->percentEncoding(e.getKey())+“=”+percentEncoding(e.getValue()))
.collect(收集器.连接(&));
返回参数字符串;
}
我得到了这样的回应
{“错误”:[{“代码”:32,“消息”:“无法验证您的身份。”}]}
我看到了您的代码,看起来您可能还没有完成所需的步骤,然后才拨打电话获取关注者 因为Twitter遵循OAuth1,所以这里是您需要做的事情。如果您确认您已经完成了这些,那么我可以帮助您完成签名过程 您正在使用的变量
- consumerKey=注册期间从twitter复制
- accesstokenSecret=注册期间从twitter复制
- oauth_令牌=作为以下步骤1的响应接收
- oauth_token_secret=作为以下步骤2的响应接收
- oauth_verifier=作为以下步骤3的响应接收
- accesstoken=作为以下步骤4的响应接收。最后,在对所有API调用进行签名时使用
我在Pathfix工作,我们将其构建为一个中间件来解决确切的问题,而无需您下载SDK。如果您与多个提供者打交道,您最终会注意到缺乏可重用性和大量不必要的代码。这可能会为您节省数小时和$$。您要实现的所有目标只需10分钟即可完成:)Twitter4J和其他几个库为您完成此任务,您有理由自己实现吗?我不知道那个库。我来看看。谢谢。如果你想在没有第三方库的情况下生成Twitter API签名,你可以参考答案。我使用Twitter4j库解决了这个问题。谢谢