Как определить токены доступа с истекшим сроком при создании сеанса?

У меня есть следующая тестовая программа:

from   rauth.service import OAuth1Service, OAuth2Service

SUPPORTED_SERVICES = {
    'twitter'  : ( 'OAuth1', 'twitter',  'https://api.twitter.com/oauth',        'request_token', 'access_token', 'authorize', 'https://api.twitter.com/1/',  None),
    'facebook' : ( 'OAuth2', 'facebook', 'https://graph.facebook.com/oauth',     None,            'access_token', 'authorize', 'https://graph.facebook.com/', 'https://www.facebook.com/connect/login_success.html'),
    'google'   : ( 'OAuth2', 'google',   'https://accounts.google.com/o/oauth2', None,            'token',        'auth',      None,                          'http://localhost'),
}

CLIENT_DATA = {
    'twitter'  : ('dummy_client_id', 'dummy_client_secret'),
    'facebook' : ('dummy_client_id', 'dummy_client_secret'),
    'google'   : ('dummy_client_id', 'dummy_client_secret'),
}

USER_TOKENS = {
    'user1' : {
        'twitter'  : ('dummy_access_token', 'dummy_access_token_secret'),
        'facebook' : ('dummy_access_token', None),
        'google'   : ('dummy_access_token', None),
    }
}

def test_google(user_id):
    service_id = 'google'
    oauthver, name, oauth_base_url, request_token_url, access_token_url, authorize_url, base_url, redirect_uri = SUPPORTED_SERVICES[service_id]
    request_token_url = oauth_base_url + '/' + (request_token_url or '')
    access_token_url  = oauth_base_url + '/' + access_token_url
    authorize_url     = oauth_base_url + '/' + authorize_url
    client_id, client_secret = CLIENT_DATA[service_id]
    google = OAuth2Service(
        client_id=client_id,
        client_secret=client_secret,
        name=name,
        authorize_url=authorize_url,
        access_token_url=access_token_url,
        base_url=base_url)
    access_token, access_token_secret = USER_TOKENS[user_id][service_id] # access_token_secret only needed for twitter (OAuth1)
    session = google.get_session(access_token)
    user = session.get('https://www.googleapis.com/oauth2/v1/userinfo').json()
    print user

test_google('user1')

Я авторизовал свое приложение для доступа к аккаунту Google user1и получил access_token. Этот токен доступа уже истек, и вывод моей программы:

{u'error': {u'code': 401, u'message': u'Invalid Credentials', u'errors': [{u'locationType': u'header', u'domain': u'global', u'message': u'Invalid Credentials', u'reason': u'authError', u'location': u'Authorization'}]}}

Я хотел бы проверить, не истек ли токен доступа при создании сеанса, а не при запросе данных. Это возможно? Как я могу проверить, действительно ли авторизован объект сеанса?

Для пояснения я пытаюсь сделать следующее:

  1. Во-первых, пусть пользователь авторизует мое приложение
  2. Сохраните токен доступа для будущего использования (в базе данных, но в тестовом коде это жестко закодировано в скрипте)
  3. Когда последующий доступ обнаруживает, что токен истек, вернитесь к шагу 1

В настоящее время у меня возникают проблемы с шагом 3. Я, конечно, могу обнаружить 401 в ответе json на мой GET, но выглядит довольно громоздким, чтобы быть вынужденным проверить все обращения к GET. То, что я пытаюсь сделать, - это убедиться, что сеанс действительно активен, когда я его создаю, и затем предположить на протяжении всей продолжительности объекта сеанса, что он останется активным. Обычно это всего несколько миллисекунд, пока мое веб-приложение обрабатывает запрос и обращается к API Google с помощью объекта сеанса OAuth.

1 ответ

Решение

Вы должны позвонить get_authorization_url во-первых, какой пользователь должен открыть и предоставить вам разрешения на доступ к своей учетной записи, взамен вы получите код от redirect_uri параметры запроса обратного вызова, которые вы можете обменять на access_token:

params = {
    'scope': 'email',
    'response_type': 'code',
    'redirect_uri': redirect_uri,
    'access_type': 'offline', # to get refresh_token
}

print google.get_authorize_url(**params)

Согласно документации этот код должен работать:

data = {
    'code': 'code you got from callback',
    'grant_type': 'authorization_code',
    'redirect_uri': 'http://localhost/oauth2',
}

response = google.get_raw_access_token(data=data)

В ответ вы получите данные в формате JSON:

{
  "access_token" : "ya29.AHE<....>n3w",
  "token_type" : "Bearer",
  "expires_in" : 3600,
  "id_token" : "eyJh<...>QwNRzc",
  "refresh_token" : "1/X86S<...>Vg4"
}

Как вы можете видеть, есть expires_in (секунды), вам нужно сохранить время, когда вы получили токен, и сравнить позже с текущим временем + expires_in,

Если токен истек, вы можете обновить его с помощью refresh_token позже, не запрашивая подтверждение пользователя снова:

response = google.get_raw_access_token(data={
    'refresh_token': refresh_token,
    'grant_type': 'refresh_token',
})
print response.content

Заметить, что refresh_token будет возвращено только в первый раз, когда пользователь авторизует приложение. Смотрите этот вопрос для деталей.

Увы, кажется, что вы не можете использовать get_auth_sessionпотому что внутренне это только извлекает access_token а все остальное отбрасывается.

Если вы получаете access_token сразу без получения аутентификации code во-первых, вы все еще получаете expires_in в обратном вызове. Из документов:

https://oauth2-login-demo.appspot.com/oauthcallback#access_token=1/fFBGRNJru1FQd44AzqT3Zg&token_type=Bearer&expires_in=3600

Другие вопросы по тегам