2014-10-18 85 views
1

我嘗試從Twitter的API獲取的oauth_token,但得到的異常:
java.io.IOException: Server returned HTTP response code: 401 for URL: https://api.twitter.com/oauth/request_token

錯誤流得到:
無法驗證的OAuth簽名和令牌

這裏是一個signatureBaseString,簽名和授權報頭例如:
signatureBaseString:POST & HTTPS%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token & oauth_callback%3Dhttp%253A%252F%252F127.0.0.1%253A8080%252Ftwlogin%26oauth_consumer_key%3D2YhNLyum1VY10UrWBMqBnatiT%26oauth_nonce%3D1413642155863 %26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1413642155%26oauth_version%3D1.0

oAuthSignature: + Ov4WEws5XULVIxx9n/Q9ybzlrM =

authorizationHeaderValue:的OAuth oauth_callback = 「HTTP%3A%2F%2F127.0.0.1%3A8080%2Ftwlogin」,oauth_consumer_key = 「2YhNLyum1VY10UrWBMqBnatiT」,oauth_nonce = 「1413642155863」,oauth_signature = 「%2BOv4WEws5XULVIxx9n%2FQ9ybzlrM%3D」,oauth_signature_method =「HMAC- SHA1" ,oauth_timestamp = 「1413642155」,oauth_version = 「1.0」

401無法驗證的OAuth簽名和令牌(https://api.twitter.com/oauth/request_token)(Java代碼)

下面是一個代碼:
的NameValuePair比較:

class NvpComparator implements Comparator<NameValuePair> { 
     @Override 
     public int compare(NameValuePair arg0, NameValuePair arg1) { 
      String name0 = arg0.getName(); 
      String name1 = arg1.getName(); 
      return name0.compareTo(name1); 
     } 
    } 

URL編碼

class OAuth{ 
... 
    public static String percentEncode(String s) { 
      return URLEncoder.encode(s, "UTF-8") 
        .replace("+", "%20").replace("*", "%2A") 
        .replace("%7E", "~"); 
    } 
... 
} 

請求方法

public String twAuth() { 
      String method = "POST"; 
      String url = "https://api.twitter.com/oauth/request_token"; 
      String oAuthConsumerKey = "2YhNLyum1VY10UrWBMqBnatiT"; 
      String oAuthConsumerSecret = ***CONSUMER_SECRET***; 
      String oAuthCallback = "http://127.0.0.1:8080/twlogin"; 
      String oAuthNonce = String.valueOf(System.currentTimeMillis()); 
      String oAuthSignatureMethod = "HMAC-SHA1"; 
      String oAuthTimestamp = String.valueOf(System.currentTimeMillis()/1000); 
      String oAuthVersion = "1.0"; 

      List<NameValuePair> allParams = new ArrayList<NameValuePair>(); 
      allParams.add(new BasicNameValuePair("oauth_callback", oAuthCallback)); 
      allParams.add(new BasicNameValuePair("oauth_consumer_key", oAuthConsumerKey)); 
      allParams.add(new BasicNameValuePair("oauth_nonce", oAuthNonce)); 
      allParams.add(new BasicNameValuePair("oauth_signature_method", oAuthSignatureMethod)); 
      allParams.add(new BasicNameValuePair("oauth_timestamp", oAuthTimestamp)); 
      allParams.add(new BasicNameValuePair("oauth_version", oAuthVersion)); 

      Collections.sort(allParams, new NvpComparator()); 

      StringBuffer params = new StringBuffer(); 
      for(int i=0;i<allParams.size();i++) 
      { 
       NameValuePair nvp = allParams.get(i); 
       if (i>0) { 
        params.append("&"); 
       } 
       params.append(nvp.getName() + "=" + OAuth.percentEncode(nvp.getValue())); 
      } 

      String signatureBaseStringTemplate = "%s&%s&%s"; 
      String signatureBaseString = String.format(signatureBaseStringTemplate, 
        OAuth.percentEncode(method), 
        OAuth.percentEncode(url), 
        OAuth.percentEncode(params.toString())); 

      String signatureKey = OAuth.percentEncode(oAuthConsumerSecret)+"&"; 

     SecretKeySpec signingKey = new SecretKeySpec(signatureKey.getBytes(), "HmacSHA1"); 
      Mac mac = Mac.getInstance("HmacSHA1"); 
      mac.init(signingKey); 
      byte[] rawHmac = mac.doFinal(signatureBaseString.getBytes()); 
      String oAuthSignature = new String(Base64.encodeBase64(rawHmac)); 

     String authorizationHeaderValueTempl = "OAuth oauth_callback=\"%s\", " + 
        "oauth_consumer_key=\"%s\", " + 
        "oauth_nonce=\"%s\", " + 
        "oauth_signature=\"%s\", " + 
        "oauth_signature_method=\"%s\", " + 
        "oauth_timestamp=\"%s\", " + 
        "oauth_version=\"%s\""; 

      String authorizationHeaderValue =String.format(authorizationHeaderValueTempl, 
        OAuth.percentEncode(oAuthCallback), 
        OAuth.percentEncode(oAuthConsumerKey), 
        OAuth.percentEncode(oAuthNonce), 
        OAuth.percentEncode(oAuthSignature), 
        OAuth.percentEncode(oAuthSignatureMethod), 
        OAuth.percentEncode(oAuthTimestamp), 
        OAuth.percentEncode(oAuthVersion)); 

     URL obj = new URL(url); 
     HttpsURLConnection con = (HttpsURLConnection) obj.openConnection(); 

     con.setRequestMethod("POST"); 
     con.setRequestProperty("Authorization", authorizationHeaderValue); 

     con.setDoOutput(true); 

     int responseCode = con.getResponseCode(); 
     BufferedReader in = new BufferedReader(
       new InputStreamReader(con.getInputStream())); 
     String inputLine; 
     StringBuffer response = new StringBuffer(); 

     while ((inputLine = in.readLine()) != null) { 
      response.append(inputLine); 
     } 
     in.close(); 

     System.out.println(response.toString()); 

     return "aboutas"; 
    } 


這裏是一個Twitter應用程序設置:
消費者密鑰(API密鑰): 2YhNLyum1VY10UrWBMqBnatiT
回調URL:http://127.0.0.1:8080/twlogin
登錄與Twitter:
網站:http://127.0.0.1:8080

任何人可以幫助我嗎?我不知道該怎麼辦..

回答

1

我設置了錯誤的時間戳,因爲我與Twitter服務器有不同的時區。

這是代碼設置爲true oAuthTimestamp:

HttpsURLConnection con = (HttpsURLConnection) 
        new URL("https://api.twitter.com/oauth/request_token").openConnection(); 
      con.setRequestMethod("HEAD"); 
      con.getResponseCode(); 
      String twitterDate= con.getHeaderField("Date"); 
      DateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.ENGLISH); 
      Date date = formatter.parse(twitterDate); 
      String oAuthTimestamp = String.valueOf(date.getTime()/1000L); 
+0

很好的答案! – user2909913 2014-12-03 11:49:46

+0

謝謝,我很高興聽到它) – Alexandr 2015-09-29 20:57:41

相關問題