请教使用 Flask-OAuthlib 申请饭否 OAuth 认证的问题

之前发表于 https://www.v2ex.com/t/177145 ,再发到这里求助下。

我对 Flask 和 OAuth 都不熟悉,所以对照了 Flask-OAuthlib 官方的 Twitter 例子,想仿写一个饭否应用,进行 OAuth 认证后通过网页发送消息。

但是我写的程序执行到 oauthorized()authorized_response() 这个函数后,返回的却一直是 None,得不到 Access token。我调试了一晚上,还是不知道自己错在什么地方了,以下是我的 fanfou.py 文件:

from flask import Flask, session, redirect, url_for, request, render_template, flash
from flask_oauthlib.client import OAuth, OAuthException

app = Flask(__name__)
app.debug = True
app.secret_key = 'AA0Zr98j/3yXR~XHH!jmN]LWX/,?RT'

oauth = OAuth(app)

fanfou = oauth.remote_app(
    'fanfou',
    base_url='http://api.fanfou.com/',
    request_token_url='http://fanfou.com/oauth/request_token',
    access_token_url='http://fanfou.com/oauth/access_token',
    authorize_url='http://fanfou.com/oauth/authorize',
    consumer_key='这里是我的consumer_key',
    consumer_secret='这里是我的consumer_secret',
)


@fanfou.tokengetter
def get_fanfou_token():
    return session.get('fanfou_token')


@app.route('/')
def index():
    if 'fanfou_token' not in session:
        flash('Unable to load fanfou_oauth.')
    return render_template('index.html')


@app.route('/tweet', methods=['POST'])
def tweet():
    status = request.form['tweet']
    if not status:
        return redirect(url_for('index'))
    resp = fanfou.post('statuses/update.json', data={
        'status': status
    })
    if resp.status == 403:
        flash('Your tweet was too long.')
    elif resp.status == 401:
        flash('Authorization error with Fanfou.')
    else:
        flash('Successfully!')
    return redirect(url_for('index'))


@app.route('/login')
def login():
    callback = url_for('oauthorized', next=request.args.get('next') or request.referrer or None, _external=True)
    return fanfou.authorize(callback=callback)


@app.route('/logout')
def logout():
    session.pop('fanfou_token', None)
    return redirect(url_for('index'))


@app.route('/oauthorized')
def oauthorized():
    next_url = request.args.get('next') or url_for('index')
    resp = fanfou.authorized_response()
    # 问题在此,总是返回 None
    if resp is None:
        flash('You denied the request to sign in.')
    if isinstance(resp, OAuthException):
        flash('Access denied: %s' % resp.message)
    session['fanfou_token'] = resp
    return redirect(next_url)


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

整个项目完整的版本可以查看这里

饭否使用的是 OAuth 1.0a,其文档在 https://github.com/FanfouAPI/FanFouAPIDoc/wiki/Oauth。我在饭否应用信息中设置的 Callback URL 是 http://127.0.0.1:5000/oauthorized

现在我想确认的是,到底是我写的有错,还是饭否 API 的问题呢?

8 comments