flask-oauthlib server doesn't play well with requests-oauthlib client
我已经启动并运行了flask-oauthlib服务器,当我使用示例中的客户端代码时,已经能够正确授权/认证。我意识到并不是我的所有客户端都将安装flask-oauthlib,所以我尝试创建一个带有requests-oauthlib的客户端,但是它在我的服务器上失败了(即使requests-oauthlib提供的" Github示例"也可以正常工作) 。
这是我的请求-oauthlib客户端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | from requests_oauthlib import OAuth2Session from flask import Flask, request, redirect, session, url_for from flask.json import jsonify import os app = Flask(__name__) client_id = 'M2GCECELADgqZNke50iShcXRjq0pyO8i72W38l7U' client_secret = 'ao5wrWp7RrUuKlgTxjmK6D7Z9dsPlI6fZc2WwkTTG4eEvXsN1q' authorization_base_url = 'http://127.0.0.1:5000/oauth/authorize' token_url = 'http://127.0.0.1:5000/oauth/token' @app.route("/") def demo(): remote = OAuth2Session(client_id) authorization_url, state = remote.authorization_url(authorization_base_url) session['oauth_state'] = state return redirect(authorization_url) @app.route("/authorized", methods=["GET"]) def authorized(): # this is where it fails remote = OAuth2Session(client_id, state=session['oauth_state']) token = remote.fetch_token(token_url, client_secret=client_secret, authorization_response=request.url) session['oauth_token'] = token return redirect(url_for('.profile')) @app.route("/profile", methods=["GET"]) def profile(): remote = OAuth2Session(client_id, token=session['oauth_token']) return jsonify(remote.get('http://127.0.0.1:5000/api/me').json()) if __name__ =="__main__": os.environ['DEBUG'] = '1' app.secret_key = os.urandom(24) app.run(host='localhost', port=8000,debug=True, use_reloader=False) |
在服务器上,这是token_handler。当前它返回None,我试图让它返回一个字典和一个json编码的字典,但是没有运气。
1 2 3 4 | @app.route('/oauth/token') @oauth.token_handler def access_token(): return None |
我的服务器代码的其余部分直接取自flask-oauthlib示例
为什么此方法可用于一个oauthlib客户端,但不能与另一个客户端一起使用?我是oauthlib的新手,所以也许我错过了一些愚蠢的简单操作?
编辑:我正在使用:
1 2 3 4 5 6 | oauthlib 0.6.1 flask-oauthlib 0.4.3 requests 2.2.1 requests-oauthlib 0.4.0 flask 0.10.1 python 2.7 |
编辑#2:request-oauthlib客户端的日志记录:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | Requesting url http://127.0.0.1:5000/oauth/token using method POST. Supplying headers {u'Accept': u'application/json'} and data {u'code': u'vG7shZebClhAjzmSUQuHoqlXNrPTVr', u'client_secret': u'qdlmQvf5tdSVxFqixeE4wOKxe3awfEbsymCOpjeTIZEaWjbbB5', u'grant_type': u'authorization_code', u'client_id': u'EXewK3X3dU1NiWk7AfNj43jrhpSy8bHQm1mOHC96'} Passing through key word arguments {'auth': None}. Prepared fetch token request body grant_type=authorization_code&code=vG7shZebClhAjzmSUQuHoqlXNrPTVr&client_id=EXewK3X3dU1NiWk7AfNj43jrhpSy8bHQm1mOHC96&client_secret=qdlmQvf5tdSVxFqixeE4wOKxe3awfEbsymCOpjeTIZEaWjbbB5 Request to fetch token completed with status 405. Response headers were CaseInsensitiveDict({'date': 'Tue, 25 Feb 2014 21:19:32 GMT', 'content-length': '178', 'content-type': 'text/html', 'allow': 'HEAD, OPTIONS, GET', 'server': 'Werkzeug/0.9.4 Python/2.7.5+'}) and content <!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 3.2 Final//EN"> 405 Method Not Allowed Method Not Allowed <p>The method is not allowed for the requested URL.</p> . Invoking 0 token response hooks. 127.0.0.1 - - [25/Feb/2014 14:19:32]"GET /authorized?state=qPJnIJctmsTbojT2nTOkgRNwgnU8vF&code=vG7shZebClhAjzmSUQuHoqlXNrPTVr HTTP/1.1" 500 - Traceback (most recent call last): .... .... ValueError: No JSON object could be decoded |
编辑#3:服务器的flask-oauthlib日志记录:
1 2 3 4 5 6 7 8 9 10 11 12 13 | Found redirect_uri None. Validate client u'EXewK3X3dU1NiWk7AfNj43jrhpSy8bHQm1mOHC96' Found default redirect uri 'http://localhost:8000/authorized' Found default scopes ['email'] 127.0.0.1 - - [25/Feb/2014 14:19:30]"GET /oauth/authorize?response_type=code&client_id=EXewK3X3dU1NiWk7AfNj43jrhpSy8bHQm1mOHC96&state=qPJnIJctmsTbojT2nTOkgRNwgnU8vF HTTP/1.1" 200 - Fetched credentials from request {'state': u'qPJnIJctmsTbojT2nTOkgRNwgnU8vF', 'redirect_uri': None, 'response_type': u'code', 'client_id': u'EXewK3X3dU1NiWk7AfNj43jrhpSy8bHQm1mOHC96'}. Found redirect_uri None. Validate client u'EXewK3X3dU1NiWk7AfNj43jrhpSy8bHQm1mOHC96' Found default redirect uri 'http://localhost:8000/authorized' Persist authorization code {u'state': u'qPJnIJctmsTbojT2nTOkgRNwgnU8vF', u'code': u'vG7shZebClhAjzmSUQuHoqlXNrPTVr'} for client u'EXewK3X3dU1NiWk7AfNj43jrhpSy8bHQm1mOHC96' Authorization successful. 127.0.0.1 - - [25/Feb/2014 14:19:32]"POST /oauth/authorize HTTP/1.1" 302 - 127.0.0.1 - - [25/Feb/2014 14:19:32]"POST /oauth/token HTTP/1.1" 405 - |
编辑#4:服务器的oauthlib日志记录:
1 2 3 4 5 6 7 8 9 10 11 12 13 | Validating redirection uri None for client EXewK3X3dU1NiWk7AfNj43jrhpSy8bHQm1mOHC96. Using default redirect_uri http://localhost:8000/authorized. Validating access to scopes ['email'] for client u'EXewK3X3dU1NiWk7AfNj43jrhpSy8bHQm1mOHC96' (). 127.0.0.1 - - [25/Feb/2014 14:12:30]"GET /oauth/authorize?response_type=code&client_id=EXewK3X3dU1NiWk7AfNj43jrhpSy8bHQm1mOHC96&state=oHvelCpzosGfJd7ZzCeBvsmRANmipb HTTP/1.1" 200 - Dispatching response_type code request to <oauthlib.oauth2.rfc6749.grant_types.authorization_code.AuthorizationCodeGrant object at 0x2db44d0>. Validating redirection uri None for client EXewK3X3dU1NiWk7AfNj43jrhpSy8bHQm1mOHC96. Using default redirect_uri http://localhost:8000/authorized. Validating access to scopes [u'email'] for client u'EXewK3X3dU1NiWk7AfNj43jrhpSy8bHQm1mOHC96' (). Pre resource owner authorization validation ok for <oauthlib.common.Request object at 0x7fb104026210>. Created authorization code grant {u'state': u'oHvelCpzosGfJd7ZzCeBvsmRANmipb', u'code': u'yAZZwtCd1IyAeBtHEgg4YTnHl46Ddf'} for request <oauthlib.common.Request object at 0x7fb104026210>. Saving grant {u'state': u'oHvelCpzosGfJd7ZzCeBvsmRANmipb', u'code': u'yAZZwtCd1IyAeBtHEgg4YTnHl46Ddf'} for <oauthlib.common.Request object at 0x7fb104026210>. 127.0.0.1 - - [25/Feb/2014 14:12:32]"POST /oauth/authorize HTTP/1.1" 302 - 127.0.0.1 - - [25/Feb/2014 14:12:32]"POST /oauth/token HTTP/1.1" 405 - |
记录器非常清晰。
1 2 3 4 5 | Requesting url http://127.0.0.1:5000/oauth/token using method POST. Request to fetch token completed with status 405. 405 Method Not Allowed Method Not Allowed <p>The method is not allowed for the requested URL.</p> |
这意味着您无法发布到
您可以更改示例:
1 2 3 4 | @app.route('/oauth/token', methods=['POST']) @oauth.token_handler def access_token(): return None |
或者您可以使用GET方法请求访问令牌,我相信可以在request-oauthlib中设置。