2013-04-18 31 views
6

Tôi đã thực hiện sau đây của một khách hàng twitter sử dụng rauth (OAuth1), dựa trên twitter-timeline-cli.py kịch bản trong rauth ví dụ:Tái sử dụng OAuth1 phép mã thông báo với rauth

from rauth.service import OAuth1Service 

class TwitterClient: 

    KNOWN_USERS = { 
     'user1' : ("xxx", "yyy", "2342354"), # These should be real tokens 
    } 

    def __init__(self): 
     # Get a real consumer key & secret from https://dev.twitter.com/apps/new 
     self.twitter = OAuth1Service(
      name='twitter', 
      consumer_key=TWITTER_CONSUMER_KEY, 
      consumer_secret=TWITTER_CONSUMER_SECRET, 
      request_token_url='https://api.twitter.com/oauth/request_token', 
      access_token_url='https://api.twitter.com/oauth/access_token', 
      authorize_url='https://api.twitter.com/oauth/authorize', 
      base_url='https://api.twitter.com/1/') 

    def authorize(self): 
     request_token, request_token_secret = self.twitter.get_request_token() 
     authorize_url = self.twitter.get_authorize_url(request_token) 
     print 'Visit this URL in your browser: ' + authorize_url 
     pin = raw_input('Enter PIN from browser: ') 
     return request_token, request_token_secret, pin 

    def init_session(self, user): 
     if user in self.KNOWN_USERS : 
      request_token, request_token_secret, pin = self.KNOWN_USERS[user] 
     else: 
      request_token, request_token_secret, pin = self.authorize() 
     session = self.twitter.get_auth_session(request_token, 
               request_token_secret, 
               method='POST', 
               data={'oauth_verifier': pin}) 
     return session 

    def list_tweets(self, user): 
     session = self.init_session(user) 
     params = {'include_rts': 1, # Include retweets 
        'count': 10}  # 10 tweets 

     r = session.get('statuses/home_timeline.json', params=params) 

     for i, tweet in enumerate(r.json(), 1): 
      handle = tweet['user']['screen_name'].encode('utf-8') 
      text = tweet['text'].encode('utf-8') 
      print '{0}. @{1} - {2}'.format(i, handle, text) 

tc = TwitterClient() 

tc.list_tweets('user1') 

Ý tưởng được rằng, nếu người dùng là không biết, anh ta được yêu cầu cho phép ứng dụng. Mặt khác, nếu người dùng đã ủy quyền cho ứng dụng này, các mã thông báo ủy quyền (request_token, request_token_secret, pin) sẽ được sử dụng lại (thông thường các mã thông báo sẽ nằm trong cơ sở dữ liệu, trong thời gian này, chúng được mã hóa cứng trong script)

Nhưng điều này không làm việc:

Traceback (most recent call last): 
    File "my-twitter-timeline-cli.py", line 56, in <module> 
    tc.list_tweets('user1') 
    File "my-twitter-timeline-cli.py", line 43, in list_tweets 
    session = self.init_session(user) 
    File "my-twitter-timeline-cli.py", line 39, in init_session 
    data={'oauth_verifier': pin}) 
    File ".../lib/python2.7/site-packages/rauth/service.py", line 326, in get_auth_session 
    **kwargs) 
    File ".../lib/python2.7/site-packages/rauth/service.py", line 299, in get_access_token 
    process_token_request(r, decoder, key_token, key_token_secret) 
    File ".../lib/python2.7/site-packages/rauth/service.py", line 25, in process_token_request 
    raise KeyError(PROCESS_TOKEN_ERROR.format(key=bad_key, raw=r.content)) 
KeyError: 'Decoder failed to handle oauth_token with data as returned by provider. A different decoder may be needed. Provider returned: <?xml version="1.0" encoding="UTF-8"?>\n<hash>\n <error>Invalid/expired Token</error>\n <request>/oauth/access_token</request>\n</hash>\n' 

có thể tái sử dụng OAuth1 thẻ ủy quyền?

Trả lời

14

Tôi đã hiểu lầm toàn bộ quá trình. Chúng tôi không cần phải lưu request_token, request_token_secretpin, nhưng access_tokenaccess_token_secret.

Quá trình này thực sự là:

  1. Sử dụng request_token, request_token_secretpin để có được access_tokenaccess_token_secret
  2. Lưu access_tokenaccess_token_secret (cơ sở dữ liệu, hoặc bất cứ điều gì)
  3. Tiếp theo thời gian, tái sử dụng access_tokenaccess_token_secret

Đây là mã kiểm tra đã sửa của tôi:

from rauth.service import OAuth1Service 

class TwitterClient: 

    KNOWN_USERS = { # (access_token, access_token_secret) 
     'user1' : ("xxx", "yyy") 
    } 

    def __init__(self): 
     # Get a real consumer key & secret from https://dev.twitter.com/apps/new 
     self.twitter = OAuth1Service(
      name='twitter', 
      consumer_key=TWITTER_CONSUMER_KEY, 
      consumer_secret=TWITTER_CONSUMER_SECRET, 
      request_token_url='https://api.twitter.com/oauth/request_token', 
      access_token_url='https://api.twitter.com/oauth/access_token', 
      authorize_url='https://api.twitter.com/oauth/authorize', 
      base_url='https://api.twitter.com/1/') 

    def new_session(self): 
     request_token, request_token_secret = self.twitter.get_request_token() 
     authorize_url = self.twitter.get_authorize_url(request_token) 
     print 'Visit this URL in your browser: ' + authorize_url 
     pin = raw_input('Enter PIN from browser: ') 
     session = self.twitter.get_auth_session(request_token, 
               request_token_secret, 
               method='POST', 
               data={'oauth_verifier': pin}) 
     print session.access_token, session.access_token_secret # Save this to database 
     return session 

    def reuse_session(self, user): 
     access_token, access_token_secret = self.KNOWN_USERS[user] 
     session = self.twitter.get_session((access_token, access_token_secret)) 
     return session 

    def init_session(self, user): 
     if user in self.KNOWN_USERS : session = self.reuse_session(user) 
     else      : session = self.new_session() 
     return session 

    def list_tweets(self, user): 
     session = self.init_session(user) 
     params = {'include_rts': 1, # Include retweets 
        'count': 10}  # 10 tweets 

     r = session.get('statuses/home_timeline.json', params=params) 

     for i, tweet in enumerate(r.json(), 1): 
      handle = tweet['user']['screen_name'].encode('utf-8') 
      text = tweet['text'].encode('utf-8') 
      print '{0}. @{1} - {2}'.format(i, handle, text) 

tc = TwitterClient() 

tc.list_tweets('user1') 
+0

Cảm ơn bạn rất nhiều vì mã này. Một câu hỏi, mặc dù ... nếu tôi không quan tâm đến xác minh người dùng, nhưng chỉ sử dụng API luồng công khai? Làm thế nào để tôi có được xung quanh 'oauth_verifier' và toàn bộ mã PIN? – Clev3r

+0

Ahah, có cùng một vấn đề với API Quickbooks và điều này làm việc cho tôi! – John

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