Reuse OAuth1 authorization tokens with rauth

*爱你&永不变心* 提交于 2019-12-03 09:59:43

问题


I have the following implementation of a twitter client using rauth (OAuth1), based on the twitter-timeline-cli.py script in the rauth examples:

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')

The idea is that, if the user is not known, he is requested to authorize the application. If, on the other hand, the user has already authorized this application, the authorization tokens (request_token, request_token_secret, pin) should be reused (normally the tokens would be in a database; for the time being, they are hard-coded in the script)

But this is not working:

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'

Is it possible to reuse OAuth1 authorization tokens?


回答1:


I was misunderstanding the whole process. We do not need to save the request_token, request_token_secret and pin, but the access_token and the access_token_secret.

The process is actually:

  1. Use request_token, request_token_secret and pin to get access_token and access_token_secret
  2. Save access_token and access_token_secret (to database, or whatever)
  3. Next time, reuse access_token and access_token_secret

This is my corrected test code:

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')


来源:https://stackoverflow.com/questions/16078366/reuse-oauth1-authorization-tokens-with-rauth

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!