" Facebook的响应无效"使用Flask-Oauthlib通过Facebook进行身份验证时

时间:2014-11-04 02:46:52

标签: python authentication oauth flask facebook-oauth

我一直得到一个"来自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更改而导致的库错误,但我会很感激任何指针!

1 个答案:

答案 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")