2013-05-24 5 views
0

Редактирование 2: Когда токен не работает, oauth дает {"error":{"message":"This authorization code has been used.","type":"OAuthException","code":100}}Facebook приложение: токен доступа истекает с помощью XMLHttpRequest?

Редактировать: Это также случается при обычной навигации по страницам.

Мои токены доступа к facebook заканчиваются во второй раз, когда я использую XMLHttpRequest. Маркер доступа не истекает, когда я перемещаюсь в приложении в противном случае. Я использую приложение Flask для python с Heroku. При загрузке страницы он получает фишку с 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 

Это похоже на работу для страниц можно перемещаться в браузере, но и для запросы XMLHttpRequest Истечение маркера. Ответ для этих запросов Ajax дает код ошибки вместо перенаправления, когда токен истек. Пользователю сообщается, что срок его сессии истек, и ему предлагается обновить страницу.

Есть ли у кого-нибудь идеи о том, почему токены заканчиваются с помощью Ajax?

ответ

0

Код 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 
Смежные вопросы