【问题标题】:Facebook app: Access token expires with XMLHttpRequest?Facebook 应用程序:访问令牌随 XMLHttpRequest 过期?
【发布时间】:2023-04-08 19:06:01
【问题描述】:

编辑 2:当令牌失败时,oauth 会给出{"error":{"message":"This authorization code has been used.","type":"OAuthException","code":100}}

编辑:这也偶尔会在正常页面导航期间发生。

我第二次使用 XMLHttpRequest 时,我的 facebook 用户访问令牌即将过期。否则,当我在应用程序中导航时,访问令牌不会过期。我正在使用带有 Heroku 的 python Flask 应用程序。当页面加载时,它会获得带有get_token 的令牌:

def fbapi_get_string(path,
    domain=u'graph', params=None, access_token=None,
    encode_func=urllib.urlencode):
    """Make an API call"""

    if not params:
        params = {}
    params[u'method'] = u'GET'
    if access_token:
        params[u'access_token'] = access_token

    for k, v in params.iteritems():
        if hasattr(v, 'encode'):
            params[k] = v.encode('utf-8')

    url = u'https://' + domain + u'.facebook.com' + path
    params_encoded = encode_func(params)
    url = url + params_encoded
    result = requests.get(url).content

    return result


def fbapi_auth(code):
    params = {'client_id': app.config['FB_APP_ID'],
              'redirect_uri': request.url,
              'client_secret': app.config['FB_APP_SECRET'],
              'code': code}

    result = fbapi_get_string(path=u"/oauth/access_token?", params=params,
                              encode_func=simple_dict_serialisation)
    print result
    pairs = result.split("&", 1)
    result_dict = {}
    for pair in pairs:
        (key, value) = pair.split("=")
        result_dict[key] = value
    return (result_dict["access_token"], result_dict["expires"])
def get_token():

    if request.args.get('code', None):
        return fbapi_auth(request.args.get('code'))[0]

    cookie_key = 'fbsr_{0}'.format(FB_APP_ID)

    if cookie_key in request.cookies:

        c = request.cookies.get(cookie_key)
        encoded_data = c.split('.', 2)

        sig = encoded_data[0]
        data = json.loads(urlsafe_b64decode(str(encoded_data[1]) + (64-len(encoded_data[1])%64)*"="))

        if not data['algorithm'].upper() == 'HMAC-SHA256':
            raise ValueError('unknown algorithm {0}'.format(data['algorithm']))

        h = hmac.new(FB_APP_SECRET, digestmod=hashlib.sha256)
        h.update(encoded_data[1])
        expected_sig = urlsafe_b64encode(h.digest()).replace('=', '')

        if sig != expected_sig:
            raise ValueError('bad signature')

        params = {
            'client_id': FB_APP_ID,
            'client_secret': FB_APP_SECRET,
            'redirect_uri': '',
            'code': data['code']
        }

        from urlparse import parse_qs
        r = requests.get('https://graph.facebook.com/oauth/access_token', params=params)
        token = parse_qs(r.content).get('access_token')
        return token

None 在没有令牌时从get_token 返回。当None被返回或者如果用户没有给予适当的权限redirect(oauthLoginUrl())被调用:

def oauthLoginUrl():
    fb_login_uri = ("https://www.facebook.com/dialog/oauth"
                    "?client_id=%s&redirect_uri=%s" %
                    (app.config['FB_APP_ID'], request.url))

    if app.config['FBAPI_SCOPE']:
        fb_login_uri += "&scope=%s" % ",".join(app.config['FBAPI_SCOPE'])
    return fb_login_uri

这似乎适用于在浏览器中导航的页面,但对于 XMLHttpRequests,令牌过期。当令牌过期时,这些 Ajax 请求的响应会给出错误代码而不是重定向。用户被告知他们的会话已过期并被要求刷新页面。

有没有人知道为什么令牌会随着 Ajax 过期?

【问题讨论】:

    标签: python ajax facebook xmlhttprequest flask


    【解决方案1】:

    oauth 代码不能多次使用。 heroku 模板已过时。将get_token() 函数替换为:

    def get_token():
    
        if request.args.get('code', None):
            token = fbapi_auth(request.args.get('code'))
            session['accessToken'] = token[0]
            session['expiry'] = time.time() + int(token[1])
            return token[0]
    
        # Check if we have the token already and that it has not expired
        if 'accessToken' in session:
            if session['expiry'] < time.time():
                return None
            return session['accessToken']
    
        cookie_key = 'fbsr_{0}'.format(FB_APP_ID)
    
        if cookie_key in request.cookies:
    
            c = request.cookies.get(cookie_key)
            encoded_data = c.split('.', 2)
    
            sig = encoded_data[0]
            data = json.loads(urlsafe_b64decode(str(encoded_data[1]) + (64-len(encoded_data[1])%64)*"="))
    
            if not data['algorithm'].upper() == 'HMAC-SHA256':
                raise ValueError('unknown algorithm {0}'.format(data['algorithm']))
    
            h = hmac.new(FB_APP_SECRET, digestmod=hashlib.sha256)
            h.update(encoded_data[1])
            expected_sig = urlsafe_b64encode(h.digest()).replace('=', '')
    
            if sig != expected_sig:
                raise ValueError('bad signature')
    
            params = {
                'client_id': FB_APP_ID,
                'client_secret': FB_APP_SECRET,
                'redirect_uri': '',
                'code': data['code']
            }
    
            from urlparse import parse_qs
            r = requests.get('https://graph.facebook.com/oauth/access_token', params=params)
            token = parse_qs(r.content).get('access_token')
            if token:
                # Save token
                session['accessToken'] = token;
                session['expiry'] = time.time() + int(parse_qs(r.content).get('expires'))
            return token
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-19
      • 2012-04-12
      • 2013-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-05
      相关资源
      最近更新 更多