質問

The provided example in rauth is using the PIN instead of the callback. I don't understand how this should work via web callback.

1) Minor problem:

According to twitter, if oauth_callback URL is passed in, then it should be used instead whatever entry is in the https://dev.twitter.com settings. However this doesn't seem to be true, if I dont set it to http://127.0.0.1:8080/twitter/authorized it would never get to that Url after a successful authorization.

app.add_url_rule('/twitter/login', view_func=views.twitter_login)  
app.add_url_rule('/twitter/authorized', 'twitter_authorized', view_func=views.twitter_authorized)

def twitter_login():
    request_token, request_token_secret = twitter.get_request_token()
    redirect_uri = url_for('twitter_authorized', _external=True)
    params = {'oauth_callback': redirect_uri, 'request_token':request_token}
    return redirect(twitter.get_authorize_url(**params))

2) Major problem is here:

I can see the request.args has both ['oauth_token'] and ['oauth_verifier']. But I don't understand how to use them to get the twitter session for obtaining user details such as picture and display name:

def twitter_authorized():
    tw_session = twitter.get_auth_session(request_token ??? , request_token_secret ???)
    resp = tw_session.get("account/verify_credentials.json", params={'format':'json'})    
    me = resp.json()
    user = User.get_or_create(...)

    if user:  
        login_user(user)            
    return redirect(url_for('index'))

If someone could shed some light on this, would be highly appreciated.

役に立ちましたか?

解決

Here's a working Twitter sign-in examples using Flask based on the Facebook example:

'''
    twitter
    -------

    A simple Flask demo app that shows how to login with Twitter via rauth.

    Please note: you must do `from twitter import db; db.create_all()` from
    the interpreter before running this example!
'''

from flask import (Flask, flash, request, redirect, render_template, session,
                url_for)
from flask.ext.sqlalchemy import SQLAlchemy

from rauth.service import OAuth1Service
from rauth.utils import parse_utf8_qsl


# Flask config
SQLALCHEMY_DATABASE_URI = 'sqlite:///twitter.db'
SECRET_KEY = '\xfb\x12\xdf\xa1@i\xd6>V\xc0\xbb\x8fp\x16#Z\x0b\x81\xeb\x16'
DEBUG = True
TW_KEY = 'oZSbVzKCeyAZTDxw1RKog'
TW_SECRET = 'TuNoqA6NzEBS3Zrb8test7bxQfKTlBfLTXsZ8RaKAo'

# Flask setup
app = Flask(__name__)
app.config.from_object(__name__)
db = SQLAlchemy(app)

# rauth OAuth 1.0 service wrapper
twitter = OAuth1Service(
    name='twitter',
    consumer_key=TW_KEY,
    consumer_secret=TW_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.1/')


# models
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)
    fb_id = db.Column(db.String(120))

    def __init__(self, username, fb_id):
        self.username = username
        self.fb_id = fb_id

    def __repr__(self):
        return '<User %r>' % self.username

    @staticmethod
    def get_or_create(username, fb_id):
        user = User.query.filter_by(username=username).first()
        if user is None:
            user = User(username, fb_id)
            db.session.add(user)
            db.session.commit()
        return user


# views
@app.route('/')
def index():
    return render_template('login.html')


@app.route('/twitter/login')
def login():
    oauth_callback = url_for('authorized', _external=True)
    params = {'oauth_callback': oauth_callback}

    r = twitter.get_raw_request_token(params=params)
    data = parse_utf8_qsl(r.content)

    session['twitter_oauth'] = (data['oauth_token'],
                                data['oauth_token_secret'])
    return redirect(twitter.get_authorize_url(data['oauth_token'], **params))


@app.route('/twitter/authorized')
def authorized():
    request_token, request_token_secret = session.pop('twitter_oauth')

    # check to make sure the user authorized the request
    if not 'oauth_token' in request.args:
        flash('You did not authorize the request')
        return redirect(url_for('index'))

    try:
        creds = {'request_token': request_token,
                'request_token_secret': request_token_secret}
        params = {'oauth_verifier': request.args['oauth_verifier']}
        sess = twitter.get_auth_session(params=params, **creds)
    except Exception, e:
        flash('There was a problem logging into Twitter: ' + str(e))
        return redirect(url_for('index'))

    verify = sess.get('account/verify_credentials.json',
                    params={'format':'json'}).json()

    User.get_or_create(verify['screen_name'], verify['id'])

    flash('Logged in as ' + verify['name'])
    return redirect(url_for('index'))


if __name__ == '__main__':
    db.create_all()
    app.run()

Hope that helps!

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top