为Twitter API生成签名的正确方法是什么?

问题描述

这是我的请求代码。 aa 表示我的使用者密钥,而bb是 userAcessTokenSecret 。为了安全起见,我更改了值。我不知道是因为 cursor 参数还是由于对值和键进行编码和哈希处理的原因。

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

下面的代码包含我的辅助函数。

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,nonce));
    String res = method +  "&" + percentEncoding(url)
            + "&" + generateSortedParameterString(parameters,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 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;

}

我收到了这个回复

{“错误”:[{“代码”:32,“消息”:“无法验证您的身份。”}]}

解决方法

我看到了您的代码,看起来您可能没有完成所需的步骤,然后才致电获取关注者。

由于Twitter遵循OAuth1,因此您需要执行此操作。如果您确认已完成这些操作,那么我可以帮助您进行签名。

您正在使用的变量

  • consumerKey =在注册过程中从推特复制
  • accesstokenSecret =注册时从Twitter复制
  • oauth_token =作为以下步骤1的响应收到
  • oauth_token_secret =从下面的步骤2中收到作为响应
  • oauth_verifier =从下面的步骤3中收到作为响应
  • accesstoken =作为以下步骤4的响应收到。最后在签署所有API调用时使用

twitter遵循的OAuth 1.0步骤

  1. 获取oauth_token对https://api.twitter.com/oauth/request_token进行签名的呼叫。 Twitter将返回oauth_token和oauth_token_secret
  2. 将用户重定向到https://api.twitter.com/oauth/authorize?oauth_token={{oauth_token}}
  3. 用户身份验证,Twitter会将代码发送到您的重定向URL
  4. 然后将已签名的请求发送到https://api.twitter.com/oauth/access_token以接收access_token

每个步骤的签名过程都相同,只是对baseString和签名密钥进行了更改。如果您已实现步骤1的签名逻辑。其他所有人都应该工作。

如果您还没有完成上述步骤,而在第一步中却难以进行签名,那么我将为您提供签名的基本结构。确认吗?

我在Pathfix工作,我们将其构建为中间件,以解决确切的问题,而无需下载SDK。如果您与多个提供程序打交道,您最终将注意到缺乏可重用性和大量不必要的代码。这样可以节省您的时间和资金。您尝试实现的所有目标最多花费10分钟:)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...