2013-04-18 5 views
6

Mam następujący wdrożenie twitter kliencie za pomocą rauth (OAuth1), na podstawie scenariusza twitter-timeline-cli.py w przykładach rauth:upoważnienie Reuse OAuth1 żetony z 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') 

Pomysł jest, że jeśli użytkownik jest nieznany, jest proszony o autoryzację wniosku. Jeśli, z drugiej strony, użytkownik już autoryzował tę aplikację, to tokeny autoryzacyjne (request_token, request_token_secret, pin) powinny być ponownie użyte (zwykle tokeny znajdują się w bazie danych, na razie są one zakodowane skrypt)

Ale to nie działa:

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' 

Czy możliwe jest ponowne OAuth1 tokeny autoryzacji?

Odpowiedz

14

Nie zrozumiałem całego procesu. Nie trzeba zapisywać wartości request_token, request_token_secret i pin, ale access_token i .

Proces jest w rzeczywistości:

  1. Zastosowanie request_token, request_token_secret i pin dostać access_token i access_token_secret
  2. Zapisz access_token i access_token_secret (do bazy danych, lub cokolwiek)
  3. Następnym razem, ponowne access_token i access_token_secret

To jest mój skorygowany kod testowy:

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

Dziękuję bardzo za ten kod. Pytanie jednak ... co jeśli nie interesuje mnie weryfikacja użytkownika, a jedynie korzystanie z publicznego strumienia API? Jak mogę obejść 'oauth_verifier' i cały kod PIN? – Clev3r

+0

Ahah, miał ten sam problem z API Quickbooks i to działało dla mnie! – John