我一直得到一个"来自Facebook的无效回复"在构建示例代码here时使用Oauthlib在Facebook上进行身份验证时出错。
我已经概述了以下相关代码的部分。
设定:
设置Oauth请求对象。
未图示:导航路线和Flask应用初始化。
from flask_oauthlib.client import OAuth, OAuthException
oauth = OAuth()
facebook = oauth.remote_app('facebook',
base_url='https://graph.facebook.com/',
request_token_url=None,
access_token_url='/oauth/access_token',
authorize_url='https://www.facebook.com/dialog/oauth',
consumer_key=config.get("app_id"),
consumer_secret=config.get("app_secret"),
request_token_params={'scope': 'public_profile,email'}
)
@facebook.tokengetter
def get_facebook_token():
if current_user.is_authenticated():
return current_user.get_facebook_token()
else:
return None
登录处理程序:
将用户发送到此处以开始此过程,并将facebook回调的网址附加到根网址。
@app.route('/facebook/login')
def facebook_login():
return facebook.authorize(callback="http://example.com%s" % url_for('facebook_callback'))
Facebook回调,问题来源:
从这里我可以获得返回代码(可能是令牌),但是Oauthlib无法正确解析它。
@app.route('/facebook/callback')
def facebook_callback(response):
response = facebook.authorized_response()
if response is None:
flash("You denied the request to sign in.", "error")
return redirect(url_for('index'))
if isinstance(response, OAuthException):
flash("Access denied: %s" % response.message, "error")
return redirect(url_for('index'))
# Request fails here, returns the redirect above.
从倾销请求args中我可以清楚地看到,在被定向到Facebook并成功连接之后,有一个很长的令牌被返回到回调中,行为是'?code = 1234567890-abcdefghijklmnop&#39 ;然而,实际上尝试通过此方式进行身份验证失败了"来自Facebook"的无效响应。
这是一个示例请求转储:
ImmutableMultiDict([('code', 'AQAPedwWavTb_cBx6NVy-qy3AL5YPr780oG5tA1LfITpVwkk-kr_4I0lG6B-vlhcYEubhuKhEM46bPs-1WpWUpJzcWfhkQ64lIkdLm9uSHSqeBHBM_6zw7SDpvVmGK-JKWBpAqRJuBKenl9zslQizthox96104iiul0uYQY67cmZgPXZi9uL-mcgZ5dRj387eKJIjNninBXxwCGgFkg5kLVHYt7t0ktUH58stYlxn2f98AXuSlrIvWsA5NeHsVbM8XY0XQrDrNbCvjDmEwHQGkZ3uZRbyaecN7MAi0bM0TrZzpuQ8j3M34DnQp_v9n4ktM4')])
使用基于Twitter样本的类似代码,我认为这可能是由于Facebook API更改而导致的库错误,但我会很感激任何指针!
答案 0 :(得分:1)
对于今后偶然发现谷歌的人,我在一个可以阅读here的解决方案中解决了这个问题。
嘿那里,我以非常黑客的方式解决了这个问题,我不这样做 推荐用于生产环境,但我最终找到了 在我上一条消息发布几天后发布。当你向Facebook询问访问令牌时,它不会给你一个 以您期望的方式访问令牌。我认为是什么 Facebook的失败反而是(也许是故意的) 格式化错误。
您可能会发生什么:
http://example.com/callback?access_token=00000000000
或
http://example.com/callback
将访问令牌作为POST传递 标题中的参数。实际发生的事情是Facebook回应如下:
http://example.com/callback?#access_token=0000000000
因此,对于任何服务器端语言都是 - 不可能 解析它,因为访问令牌现在只对其可见 浏览器本身。它不会传递到后端。
捕获请求:
@app.route('/facebook/translate', methods=['GET'])
def facebook_translate():
# Facebook responds with the access token as ?#access_token,
# rather than ?access_token, which is only accessible to the browser.
# This part is where things get really, really dumb.
return ''' <script type="text/javascript">
var token = window.location.href.split("access_token=")[1];
window.location = "/facebook/callback?access_token=" + token;
</script> '''
照常进行:
@app.route('/facebook/callback', methods=['GET', 'POST'])
def facebook_callback():
access_token = request.args.get("access_token")
if access_token == "undefined":
flash("You denied the request to sign in.", "error")
return redirect(url_for('index'))
graph = facebooksdk.GraphAPI(access_token)
profile = graph.get_object("me")