2010-06-03 38 views
5

Tôi đã cố gắng triển khai OAuth cho ý tưởng lập trình của mình trong Java, nhưng tôi đã thất bại thảm hại. Tôi không biết tại sao, nhưng mã của tôi không hoạt động. Mỗi khi tôi chạy chương trình của tôi, một IOException được ném với lý do "java.io.IOException: Máy chủ trả về mã phản hồi HTTP: 401" (401 có nghĩa là trái phép). Tôi đã xem xét kỹ tài liệu, nhưng tôi thực sự không hiểu tại sao nó không hoạt động. Nhà cung cấp OAuth của tôi mà tôi muốn sử dụng là twitter, nơi tôi cũng đã đăng ký ứng dụng của mình.
Cảm ơn trước
PhineasTriển khai OAuth trong Java


OAuth docs
Twitter API wiki
Class Base64Coder

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

Lời khuyên của tôi: không tái phát minh ra bánh xe, sử dụng giải pháp của người khác: http://stackoverflow.com/questions/1731966/library -cho-oauth-consumer-java – skaffman

+2

Tôi đã xem xét sử dụng thư viện cồng kềnh, nhưng tôi muốn một giải pháp phù hợp hoàn hảo. Với tôi, lập trình có nghĩa là nhiều hơn là chỉ đặt một số thư viện hoặc API được xác định trước, tôi muốn đạt được một cái nhìn vượt ra ngoài hậu trường. – phineas

Trả lời

1

Hãy thử loại bỏ các tham số "oauth_callback". Nó làm việc cho tôi. Ứng dụng tôi đang làm là một ứng dụng web.

1

Tôi biết đây là câu hỏi cũ nhưng có vẻ như phải mất một chút thời gian để tìm hiểu câu trả lời đúng. Điều này có vẻ là một trong những liên kết hàng đầu trong google. Các trang tại dev.twitter.com cũng dẫn đến hầu như không có nơi nào. Vì vậy, ở đây nó đi. Hãy xem here để biết mã xử lý đúng cách. Nó sử dụng HttpCore, nhưng nó có thể đạt được với các thư viện chuẩn.

Viết truyện ngắn.

  1. URLThư viện bộ mã hóa trong 1.6 (rất có thể sau đó trong Android cũng vậy) không tuân thủ yêu cầu API chuẩn RFC của Twitter. Mã ở đây dường như đang phản đối vấn đề một phần. Hãy xem nguồn tôi liên kết để tìm phương pháp xử lý nó một cách thích hợp.
  2. Trong khi tạo tham số chuỗi cơ sở bạn đang mã hóa mỗi cặp giá trị khóa. Nó phù hợp với hướng dẫn tại trang twitter. Dễ dàng nối thêm url được mã hóa và chuỗi tham số được tạo ra toàn bộ (cặp khóa/giá trị)
  3. Trong khi tạo chữ ký bạn đang tạo nó dựa vào đối tượng keyspec với CONSUMER_KEY được nối với phương thức mã thông báo yêu cầu đăng nhập "&" API Twitter.
  4. Theo như mã này. Đối với yêu cầu mã thông báo nó không có vẻ quan trọng cả.

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

    Cái này tuy nhiên, không connection.setRequestMethod(method);

Các vấn đề liên quan