2013-11-22 94 views
0

我想從Twitter API獲取Oauth request_token。 但是,當我運行的代碼,它是輸出「未經授權」,雖然我是一個授權用戶。 以下是輸出:嘗試從Twitter API獲取Oauth request_token時出現「未經授權」錯誤

"parameter_string=oauth_consumer_key=MlyUxiF1ihXIymYIPWZCA&oauth_nonce=7ee1983904884d45b723f6cc50306617&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1385127328&oauth_version=1.0 
signature_base_string=POST&https%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token&oauth_consumer_key%3DMlyUxiF1ihXIymYIPWZCA%26oauth_nonce%3D7ee1983904884d45b723f6cc50306617%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1385127328%26oauth_version%3D1.0 
oauth_signature=%2FOnHRfoRKyxPd9KG%2BA0HlFvE6yg%3D 
authorization_header_string=OAuth oauth_consumer_key="MlyUxiF1ihXIymYIPWZCA",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1385127328",oauth_nonce="7ee1983904884d45b723f6cc50306617",oauth_version="1.0",oauth_signature="%2FOnHRfoRKyxPd9KG%2BA0HlFvE6yg%3D" 
log4j:WARN No appenders could be found for logger (org.apache.http.impl.conn.BasicClientConnectionManager). 
log4j:WARN Please initialize the log4j system properly. 
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info. 
Unauthorized 
" 

這裏是我的全碼:

import java.io.IOException; 
import java.io.UnsupportedEncodingException; 
import java.net.URLEncoder; 
import java.security.GeneralSecurityException; 
import java.util.Date; 
import java.util.UUID; 

import javax.crypto.Mac; 
import javax.crypto.SecretKey; 
import javax.crypto.spec.SecretKeySpec; 

import org.apache.commons.codec.binary.Base64; 
import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.ResponseHandler; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.impl.client.BasicResponseHandler; 
import org.apache.http.impl.client.DefaultHttpClient; 

public class TwitterConnection { 

    public static void main(String args[]) throws UnsupportedEncodingException { 

     // System.out.println(System.getProperty("java.classpath")); 

     String oauth_signature_method = "HMAC-SHA1"; 

     String oauth_consumer_key = "MlyUxiF1ihXIymYIPWZCA"; 

     String uuid_string = UUID.randomUUID().toString(); 

     uuid_string = uuid_string.replaceAll("-", ""); 

     String oauth_nonce = uuid_string; // any relatively random alphanumeric 
              // string will work here. I used 
              // UUID minus "-" signs 

     long timestamp_at_entry = new Date().getTime(); 
     String oauth_timestamp = (new Long(timestamp_at_entry/1000)) 
       .toString(); // get current time in milliseconds, then divide by 
           // 1000 to get seconds 

     // I'm not using a callback value. Otherwise, you'd need to include it 
     // in the parameter string like the example above 

     // the parameter string must be in alphabetical order 

     String parameter_string = "oauth_consumer_key=" + oauth_consumer_key 
       + "&oauth_nonce=" + oauth_nonce + "&oauth_signature_method=" 
       + oauth_signature_method + "&oauth_timestamp=" 
       + oauth_timestamp + "&oauth_version=1.0"; 

     System.out.println("parameter_string=" + parameter_string); 

     String signature_base_string = "POST&https%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token&" 
       + URLEncoder.encode(parameter_string, "UTF-8"); 

     System.out.println("signature_base_string=" + signature_base_string); 

     String oauth_signature = ""; 

     try { 

      oauth_signature = computeSignature(signature_base_string, 
        "122595245-sPcfsJO3GRkJpjzgFLZ918OaHkxeSmwYg9WDn23Z"); // note 
                      // the 
                      // & 
                      // at 
                      // the 
                      // end. 
                      // Normally 
                      // the 
                      // user 
                      // access_token 
                      // would 
                      // go 
                      // here, 
                      // but 
                      // we 
                      // don't 
                      // know 
                      // it 
                      // yet 
                      // for 
                      // request_token 

      System.out.println("oauth_signature=" 
        + URLEncoder.encode(oauth_signature, "UTF-8")); 

     } catch (GeneralSecurityException e) { 

      // TODO Auto-generated catch block 

      e.printStackTrace(); 

     } 

     String authorization_header_string = "OAuth oauth_consumer_key=\"" 
       + oauth_consumer_key 
       + "\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"" + 

       oauth_timestamp + "\",oauth_nonce=\"" + oauth_nonce 
       + "\",oauth_version=\"1.0\",oauth_signature=\"" 
       + URLEncoder.encode(oauth_signature, "UTF-8") + "\""; 

     System.out.println("authorization_header_string=" 
       + authorization_header_string); 

     String oauth_token = ""; 

     HttpClient httpclient = new DefaultHttpClient(); 
     try { 

//   HttpParams params = new SyncBasicHttpParams(); 
//   HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
//   HttpProtocolParams.setContentCharset(params, "UTF-8"); 
//   HttpProtocolParams.setUserAgent(params, "HttpCore/1.1"); 
//   HttpProtocolParams.setUseExpectContinue(params, false); 
// 
//   HttpProcessor httpproc = new ImmutableHttpProcessor(
//     new HttpRequestInterceptor[] { 
//       // Required protocol interceptors 
//       new RequestContent(), new RequestTargetHost(), 
//       // Recommended protocol interceptors 
//       new RequestConnControl(), new RequestUserAgent(), 
//       new RequestExpectContinue() }); 
// 
//   HttpRequestExecutor httpexecutor = new HttpRequestExecutor(); 
//   HttpContext context = new BasicHttpContext(null); 
//   HttpHost host = new HttpHost(
//     "https://api.twitter.com/oauth/request_token", 443); // use 
//                   // 80 
//                   // if 
//                   // you 
//                   // want 
//                   // regular 
//                   // HTTP 
//                   // (not 
//                   // HTTPS) 
//   DefaultHttpClientConnection conn = new DefaultHttpClientConnection(); 
// 
//   context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn); 
//   context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, host); 
// 
//   // initialize the HTTPS connection 
//   SSLContext sslcontext = SSLContext.getInstance("TLS"); 
//   sslcontext.init(null, null, null); 
//   SSLSocketFactory ssf = sslcontext.getSocketFactory(); 

      // for HTTP, use this instead of the above. 
      // Socket socket = new Socket(host.getHostName(), host.getPort()); 
      // conn.bind(socket, params); 

//   BasicHttpEntityEnclosingRequest request2 = new BasicHttpEntityEnclosingRequest(
//     "POST", "https://api.twitter.com/oauth/request_token"); 
//   request2.setEntity(new StringEntity("", 
//     "application/x-www-form-urlencoded", "UTF-8")); 
//   request2.setParams(params); 
//   request2.addHeader("Authorization", authorization_header_string); // this 
//                    // is 
//                    // where 
//                    // we're 
//                    // adding 
//                    // that 
//                    // required 
//                    // "Authorization: BLAH" 
//                    // header. 
//   httpexecutor.preProcess(request2, httpproc, context); 
//   HttpResponse response2 = httpexecutor.execute(request2, conn, 
//     context); 
//   // 
      HttpPost httppost = new 
      HttpPost("https://api.twitter.com/oauth/request_token"); 

      httppost.setHeader("Authorization",authorization_header_string); 


      ResponseHandler<String> responseHandler = new 
      BasicResponseHandler(); 

      String responseBody = httpclient.execute(httppost, 
      responseHandler); 

      oauth_token = 
      responseBody.substring(responseBody.indexOf("oauth_token=") + 12, 
      responseBody.indexOf("&oauth_token_secret=")); 

      System.out.println(responseBody); 

     } 

     catch (ClientProtocolException cpe) { 
      System.out.println(cpe.getMessage()); 
     } 

     catch (IOException ioe) { 
      System.out.println(ioe.getMessage()); 
     } 

     finally { 
      httpclient.getConnectionManager().shutdown(); 
     } 
    } 

    private static String computeSignature(String baseString, String keyString) 
      throws GeneralSecurityException, UnsupportedEncodingException { 

     SecretKey secretKey = null; 

     byte[] keyBytes = keyString.getBytes(); 

     secretKey = new SecretKeySpec(keyBytes, "HmacSHA1"); 

     Mac mac = Mac.getInstance("HmacSHA1"); 

     mac.init(secretKey); 

     byte[] text = baseString.getBytes(); 

     return new String(Base64.encodeBase64(mac.doFinal(text))).trim(); 

    } 

} 

我想知道,我該如何解決這個問題,並得到了request_token。

回答

0

看看像Signpost這樣的圖書館。用所有正確的參數和&分隔符創建簽名總是很棘手,你似乎在做所有的事情。如果你只是因爲學術原因而嘗試,那麼請閱讀rfc!

+0

嗨,我使用的路標如你所說,但是當我寫的程序,並給我申請的相應憑證,它是失敗說 異常線程「main」 oauth.signpost.exception.OAuthExpectationFailedException:請求令牌或令牌祕密未在服務器回覆中設置。您使用的服務提供商可能是越野車。 \t在oauth.signpost.basic.DefaultOAuthProvider.retrieveToken(DefaultOAuthProvider.java:138) \t在oauth.signpost.basic.DefaultOAuthProvider.retrieveRequestToken(DefaultOAuthProvider.java:66)在Main.main(Main.java:30)」想知道我是否在這裏失去了一些東西。 –

0

假設您的消費者密鑰是122595245-sPcfsJO3GRkJpjzgFLZ918OaHkxeSmwYg9WDn23Z,您需要在最後附加一個和號字符以獲取簽名密鑰,如您的筆記所示。

您的簽名基準字符串是正確的(除了oauth_callback參數 - 請參閱下文),因此您的代碼可能會生成不正確的簽名。您可以使用在線簽名生成器(例如LinkedIn OAuth Test Console)來檢查您的簽名。

您似乎沒有在計算中包含oauth_callback參數。這需要設置爲您希望用戶在授權您的應用時重定向到的url,或者設置爲基於PIN的授權的「oob」。順便說一句,如果上面的代碼包含您的實際消費者密鑰和消費者密鑰,我不會在公共論壇上發佈它們。

相關問題