2010-06-03 7 views
5

자바에서 프로그래밍 아이디어를 위해 OAuth를 구현하려고했지만 비참하게 실패했습니다. 이유는 모르지만 코드는 작동하지 않습니다. 프로그램을 실행할 때마다 IOException이 "java.io.IOException : 서버가 HTTP 응답 코드를 반환했습니다 : 401"(401은 권한이 없음을 의미)이라는 이유로 throw됩니다. 문서를 자세히 살펴 보았지만 실제로 작동하지 않는 이유를 이해하지 못합니다. 내 OAuth 제공 업체는 내 앱을 등록한 트위터를 사용하고 싶습니다. 사전에
감사
피네
Twitter API wiki
Class Base64CoderJava에서 OAuth 구현

import java.io.InputStreamReader; 
import java.io.BufferedReader; 
import java.io.OutputStream; 
import java.io.IOException; 
import java.io.UnsupportedEncodingException; 
import java.net.URL; 
import java.net.URLEncoder; 
import java.net.URLConnection; 
import java.net.MalformedURLException; 
import javax.crypto.Mac; 
import javax.crypto.spec.SecretKeySpec; 
import java.security.NoSuchAlgorithmException; 
import java.security.InvalidKeyException; 

public class Request { 
    public static String read(String url) { 
     StringBuffer buffer = new StringBuffer(); 
     try { 
     /** 
     * get the time - note: value below zero 
     * the millisecond value is used for oauth_nonce later on 
     */ 
      int millis = (int) System.currentTimeMillis() * -1; 
      int time = (int) millis/1000; 

      /** 
      * Listing of all parameters necessary to retrieve a token 
      * (sorted lexicographically as demanded) 
      */ 
      String[][] data = { 
       {"oauth_callback", "SOME_URL"}, 
       {"oauth_consumer_key", "MY_CONSUMER_KEY"}, 
       {"oauth_nonce", String.valueOf(millis)}, 
       {"oauth_signature", ""}, 
       {"oauth_signature_method", "HMAC-SHA1"}, 
       {"oauth_timestamp", String.valueOf(time)}, 
       {"oauth_version", "1.0"} 
      }; 

      /** 
      * Generation of the signature base string 
      */ 
      String signature_base_string = 
       "POST&"+URLEncoder.encode(url, "UTF-8")+"&"; 
      for(int i = 0; i < data.length; i++) { 
       // ignore the empty oauth_signature field 
       if(i != 3) { 
       signature_base_string += 
        URLEncoder.encode(data[i][0], "UTF-8") + "%3D" + 
        URLEncoder.encode(data[i][1], "UTF-8") + "%26"; 
       } 
      } 
      // cut the last appended %26 
      signature_base_string = signature_base_string.substring(0, 
       signature_base_string.length()-3); 

      /** 
      * Sign the request 
      */ 
      Mac m = Mac.getInstance("HmacSHA1"); 
      m.init(new SecretKeySpec("CONSUMER_SECRET".getBytes(), "HmacSHA1")); 
      m.update(signature_base_string.getBytes()); 
      byte[] res = m.doFinal(); 
      String sig = String.valueOf(Base64Coder.encode(res)); 
      data[3][1] = sig; 

      /** 
      * Create the header for the request 
      */ 
      String header = "OAuth "; 
      for(String[] item : data) { 
       header += item[0]+"=\""+item[1]+"\", "; 
      } 
      // cut off last appended comma 
      header = header.substring(0, header.length()-2); 

      System.out.println("Signature Base String: "+signature_base_string); 
      System.out.println("Authorization Header: "+header); 
      System.out.println("Signature: "+sig); 

      String charset = "UTF-8"; 
      URLConnection connection = new URL(url).openConnection(); 
      connection.setDoInput(true); 
      connection.setDoOutput(true); 
      connection.setRequestProperty("Accept-Charset", charset); 
      connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + charset); 
      connection.setRequestProperty("Authorization", header); 
      connection.setRequestProperty("User-Agent", "XXXX"); 
      OutputStream output = connection.getOutputStream(); 
      output.write(header.getBytes(charset)); 

      BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); 

      String read; 
      while((read = reader.readLine()) != null) { 
       buffer.append(read); 
      } 
     } 
     catch(Exception e) { 
      e.printStackTrace(); 
     } 

     return buffer.toString(); 
    } 

    public static void main(String[] args) { 
     System.out.println(Request.read("http://api.twitter.com/oauth/request_token")); 
    } 
} 
+1

내 조언 : 다른 사람의 솔루션을 사용, 바퀴를 다시 발명하지 않습니다 http://stackoverflow.com/questions/1731966/library -for-oauth-consumer-java – skaffman

+2

나는 비 대한 라이브러리를 사용하는 것을 고려해 봤지만, 완벽하게 맞는 솔루션을 원했습니다. 저에게있어 프로그래밍이란 라이브러리 나 미리 정의 된 API를 togehter로 설정하는 것 이상을 의미합니다. 장면 너머로 한 눈에 들어보세요. – phineas

답변

1

매개 변수 "에 oauth_callback"를 제거하십시오


OAuth docs

. 그것은 나를 위해 일했습니다. 내가 작업 한 응용 프로그램은 웹 응용 프로그램입니다.

1

나는 이것이 오래된 질문이라는 것을 알고있다. 그러나 마침내 적절한 대답을 얻으려면 약간의 파고가 필요해 보인다. 이것은 Google의 최고 링크 중 하나 인 것처럼 보입니다. dev.twitter.com의 페이지는 거의 아무데도 이어지지 않습니다. 그래서 여기에 그것은 간다. 올바르게 처리하는 코드는 here입니다. HttpCore을 사용하지만 표준 라이브러리를 사용하여 구현할 수 있습니다.

이야기를 짧게 만듭니다.

  1. URLEncoder 라이브러리는 1.6 (대부분 Android에 해당 될 가능성이 높음)의 RFC 표준 Twitter API 요구 사항을 준수하지 않습니다. 이 코드는 부분적으로 문제를 해결하는 것으로 보입니다. 링크 된 소스를보고 적절한 방식으로 처리하는 방법을 찾으십시오.
  2. 기본 문자열 매개 변수를 만드는 동안 각 키 값 쌍을 인코딩합니다. 트위터 페이지의 가이드를 준수합니다. 인코딩 된 URL과 전체 생성 된 매개 변수 문자열 (키/값 쌍)을 추가하는 것이 더 쉽습니다.
  3. 서명을 생성하는 동안 CONSUMER_KEY에 "&"이 추가 된 keyspec 객체를 생성하는 중입니다. Twitter API.
  4. 이 코드에서까지입니다. 요청 토큰에 대해서는 전혀 중요하지 않습니다.

    connection.setRequestProperty("Accept-Charset", charset); 
    connection.setRequestProperty("Content-Type", "application/x-www-formurlencoded;charset="+ charset); 
    connection.setRequestProperty("User-Agent", "XXXX"); 
    

    이 하나, 그래도 않습니다 connection.setRequestMethod(method);