2010-07-15 32 views
8

Tôi đang thiết lập OAuth cho ứng dụng Android của mình. Để kiểm tra nó, tôi đã làm như sau: Đã thêm signpost-core-1.2.1.1.jar và signpost-commonshttp4-1.2.1.1.jar vào dự án của tôi, thêm các biến "CommonsHttpOAuthConsumer consumer" và "CommonsHttpOAuthProvider provider" và thực hiện như sau nút được click:Android OAuth: Ngoại lệ trên retrieveAccessToken()

consumer = new CommonsHttpOAuthConsumer("xxx", "yyy"); 
provider = new CommonsHttpOAuthProvider("https://api.twitter.com/oauth/request_token", 
        "https://api.twitter.com/oauth/access_token", 
        "https://api.twitter.com/oauth/authorize"); 

oauthUrl = provider.retrieveRequestToken(consumer, "myapp://twitterOauth"); 
persistOAuthData(); 
this.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(oauthUrl))); 

persistOAuthData() nào sau đây:

protected void persistOAuthData() 
{ 
    try 
    { 
     FileOutputStream providerFOS = this.openFileOutput("provider.dat", MODE_PRIVATE); 
     ObjectOutputStream providerOOS = new ObjectOutputStream(providerFOS); 
     providerOOS.writeObject(this.provider); 
     providerOOS.close(); 

     FileOutputStream consumerFOS = this.openFileOutput("consumer.dat", MODE_PRIVATE); 
     ObjectOutputStream consumerOOS = new ObjectOutputStream(consumerFOS); 
     consumerOOS.writeObject(this.consumer); 
     consumerOOS.close(); 
    } 
    catch (Exception e) { } 
} 

Vì vậy, người tiêu dùng và nhà cung cấp sẽ được lưu trước khi mở trình duyệt, như được mô tả here.

Trong phương thức onResume() Tôi tải dữ liệu nhà cung cấp và người tiêu dùng và làm như sau:

Uri uri = this.getIntent().getData(); 
    if (uri != null && uri.getScheme().equals("myapp") && uri.getHost().equals("twitterOauth")) 
    { 
     verifier = uri.getQueryParameter(oauth.signpost.OAuth.OAUTH_VERIFIER); 
     if (!verifier.equals("")) 
     { 
      loadOauthData(); 
      try 
      { 
       provider.retrieveAccessToken(consumer, verifier); 
      } 
      catch (OAuthMessageSignerException e) { 
       e.printStackTrace(); 
      } catch (OAuthNotAuthorizedException e) { 
       e.printStackTrace(); 
      } catch (OAuthExpectationFailedException e) { 
       e.printStackTrace(); 
      } catch (OAuthCommunicationException e) { 
       e.printStackTrace(); 
      }    
     } 
    } 

Vì vậy, những gì hoạt động: 1) Tôi làm được một requestToken và requestSecret. 2) Tôi nhận được oauthUrl. 3) Tôi được chuyển đến trang trình duyệt để ủy quyền ứng dụng của tôi 4) Tôi đang được chuyển hướng đến ứng dụng của mình. 5) Tôi nhận được người xác minh. Nhưng gọi truy xuấtTruy cậpToken (người tiêu dùng, người xác minh) không thành công với một OAuthCommunicationException nói "Giao tiếp với nhà cung cấp dịch vụ không thành công: null".

Có ai biết điều gì có thể là lý do không? Một số người dường như có vấn đề với requestToken, nhưng điều đó chỉ hoạt động tốt. Tôi tự hỏi nếu nó có thể là một vấn đề mà ứng dụng của tôi cũng đã bao gồm apache-mime4j-0.6.jar và httpmime-4.0.1.jar mà tôi cần để tải lên nhiều phần.

Trả lời

13

OK, tôi đã tìm ra. Có thể điều này hữu ích cho những người khác:

Trước hết, bạn không cần lưu toàn bộ đối tượng người tiêu dùng và nhà cung cấp. Tất cả những gì bạn cần làm là lưu trữ requestToken và requestSecret. May mắn thay, đó là Strings, vì vậy bạn không cần phải viết chúng vào đĩa hay bất cứ thứ gì. Chỉ cần lưu trữ chúng trong sharedPreferences hoặc một cái gì đó như thế.

Bây giờ, khi bạn nhận được chuyển hướng bằng trình duyệt và onResume() của phương pháp được gọi là, chỉ cần làm như sau:

//The consumer object was lost because the browser got into foreground, need to instantiate it again with your apps token and secret. 
consumer = new CommonsHttpOAuthConsumer("xxx", "yyy"); 

//Set the requestToken and the tokenSecret that you got earlier by calling retrieveRequestToken. 
consumer.setTokenWithSecret(requestToken, tokenSecret); 

//The provider object is lost, too, so instantiate it again. 
provider = new CommonsHttpOAuthProvider("https://api.twitter.com/oauth/request_token", 
           "https://api.twitter.com/oauth/access_token", 
           "https://api.twitter.com/oauth/authorize");  
//Now that's really important. Because you don't perform the retrieveRequestToken method at this moment, the OAuth method is not detected automatically (there is no communication with Twitter). So, the default is 1.0 which is wrong because the initial request was performed with 1.0a. 
provider.setOAuth10a(true); 

provider.retrieveAccessToken(consumer, verifier); 

Vậy là xong, bạn có thể nhận được token và bí mật với getToken() và getTokenSecret(), ngay bây giờ.

+0

thanks a lot ... này giải quyết vấn đề của tôi ... công việc tuyệt vời của Manuel – Panache

+0

Vì vậy, trong trường hợp của bạn, 'requestToken' bạn đặt trong' consumer.setOkenWithSecret' là 'oauthUrl'? và tôi có thể hỏi 'tokenSecret' là gì? Cảm ơn :) – dumbfingers

+0

Xin lỗi, tôi nghĩ rằng tôi có thể tìm ra nó, là 'requestToken' được lấy ra bằng cách sử dụng' consumer.getToken() '? – dumbfingers

0

Xin chào Manuel tôi thấy bạn cũng tránh được OAuthocalypse! heres là một ví dụ tốt để triển khai OAuth cho Twitter bằng sharedPreferences để lưu requestToken và requestSecret, giống như giải pháp của bạn. http://github.com/brione/Brion-Learns-OAuth bởi Brion Emde

heres video

hy vọng điều này giúp các nhà phát triển khác =)

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