请教使用 Flask-OAuthlib 申请饭否 OAuth 认证,但是不返回 Access token 的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
mimzy
V2EX    Flask

请教使用 Flask-OAuthlib 申请饭否 OAuth 认证,但是不返回 Access token 的问题

  •  1
     
  •   mimzy
    mookrs 2015-03-16 00:45:35 +08:00 4577 次点击
    这是一个创建于 3932 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    但是我写的程序执行到 oauthorized()authorized_response() 这个函数后,返回的却一直是 None。我调试了一晚上,还是不知道自己错在什么地方了,以下是我的 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.0,其文档在 https://github.com/FanfouAPI/FanFouAPIDoc/wiki/Oauth。我在饭否应用信息中设置的 Callback URL 是 http://127.0.0.1:5000/oauthorized

    研究大半天我头都要炸了……如果我对某些概念的理解存在偏差,请指出…… _(:з」∠)_

    8 条回复    2015-11-19 22:07:33 +08:00
    raptor
        1
    raptor  
       2015-03-16 14:17:25 +08:00   1
    不知道flask_oauthlib是怎么实现的,我用reqeusts自己做过一个实现是没问题的: https://bitbucket.org/raptorz/restclient。

    饭否似乎并不使用应用信息中注册的callback,而是使用授权页面(request_token)时传入的callback参数,另外服务器时间错误也会导致授权失败。
    mimzy
        2
    mimzy  
    OP
       2015-03-16 17:01:36 +08:00
    @raptor 感谢猛禽大大,回去我再看看。

    中午试了下渣浪微博的例子成功了,饭否就不行。

    关于 Callback URL,用这个库时只要我填上就能跳转回来,不填的话就直接留在授权成功页面了。这个我也再研究研究。
    raptor
        3
    raptor  
       2015-03-17 08:56:44 +08:00   1
    @mimzy 那我大概知道了。因为饭否在响应时默认不使用code项,即在调用access_token时不需要传入verify_code参数,所以在callback时也不会提供code,这个库估计对此没有判断,只要callback时没有code就自动出错了。这种情况只能修改库代码了
    mimzy
        4
    mimzy  
    OP
       2015-03-17 09:09:34 +08:00
    @raptor 好的!回头我再看下饭否的文档 感谢猛师傅指导~~(^0^*
    mimzy
        5
    mimzy  
    OP
       2015-11-19 02:32:39 +08:00
    @raptor 时隔半年多我又重新研究了一遍,结果发现猛师傅说得完全正确啊!这个库通过判断 oauth_verifier 这个东西调用响应方法,但是饭否没传这个值,所以只好返回 None 了。我简单改了下库已经能用了,再次感谢猛师傅~
    raptor
        6
    raptor  
       2015-11-19 09:58:38 +08:00   1
    @mimzy 哈哈,解决就好
    mimzy
        7
    mimzy  
    OP
       2015-11-19 22:06:59 +08:00
    最终解决反感:不修改 Flask-OAuthlib 这个库,而是在饭否的 Callback URL 末尾添加 ?oauth_verifier=0 ,这样传回来地址的时候 request.args 里就有了 oauth_verifier 这一项。 oauth_verifier 对于能否发消息无关紧要,但关系到 Flask-OAuthlib 判断应该调用 oauth1 还是 oauth2 的方法。
    mimzy
        8
    mimzy  
    OP
       2015-11-19 22:07:33 +08:00
    反感 -> 方案
    关于     帮助文档     自助推广系统     博客   &bsp; API     FAQ     Solana     2647 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 13:46 PVG 21:46 LAX 05:46 JFK 08:46
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86