Аутентификация в календаре с помощью Python gdata и oAuth 2 - PullRequest
4 голосов
/ 26 августа 2011

Я перевожу приложение Python с oAuth 1 на oAuth 2, которое читает пользовательский Google фид календаря.

  • С oAuth 1: Мое приложение открыло бы браузер, где пользователь может пройти аутентификацию с помощью своего GMail учетной записи и авторизовать доступ, и мое приложение получит user_token, user_secret для этого пользователя, затем авторизуйтесь в ленте календаря:

    client = gdata.calendar.client.CalendarClient(source='test')
    client.auth_token = gdata.gauth.OAuthHmacToken(app_key,
             app_secret,user_token,user_secret,gdata.gauth.ACCESS_TOKEN)
    

Этот токен, секретная пара, будет долгоживущим.

  • с oAuth 2: Я зарегистрировал свое приложение в консоли API Google и получил oAuth 2 client_id и client_secret, и изменил приложение, чтобы запросить user_token пользователя, refresh_token от https://accounts.google.com/o/oauth2/token Для библиотеки GData я применил указанный здесь патч gauth.py: http://codereview.appspot.com/4440067/

Этот access_token недолговечен.

Я немного поиграл с кодом, размещенным здесь http://codereview.appspot.com/4440067/ и работает нормально.

Мои вопросы:

-Я получаю access_token, refresh_token через вызов curl из моего приложение, и я могу успешно получить оба. Однако, когда я применяю это к этот код:

    token =
    gdata.gauth.OAuth2Token(client_id=client_id,client_secret=client_secret',
                           scope='https://www.google.com/calendar/
    feeds',user_agent='calendar-cmdline-sample/1.0')
    uri = token.generate_authorize_url()
    token.get_access_token(access_token)

Это дает мне:

Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "/Library/Python/2.6/site-packages/gdata/gauth.py", line 1267,
in get_access_token
   raise OAuth2AccessTokenError(error_msg)
gdata.gauth.OAuth2AccessTokenError

- При условии, что я могу успешно выполнить вышеизложенное, я могу сохранить токены доступа / обновления в БД. Используя python gdata lib, как я могу использовать refresh_token для запроса другого access_token (следовательно, не нужно спрашивать пользователя каждый раз, когда он использует приложение для авторизации доступа к нему)

Большое спасибо заранее!

M

1 Ответ

1 голос
/ 19 апреля 2012

Marchie,

Я не вижу остальной части трассировки вашего стека, но могу дать три конкретных проблемы с соответствующими решениями, которые решат вашу общую проблему.

Проблема I: значение redirect_uri не задано для объекта.

Обратите внимание, как тело запроса указано в get_access_token:

body = urllib.urlencode({
  'grant_type': 'authorization_code',
  'client_id': self.client_id,
  'client_secret': self.client_secret,
  'code': code,
  'redirect_uri': self.redirect_uri,
  'scope': self.scope
  })

Это зависит от redirect_uri свойство, устанавливаемое на объекте к значению, которое было первоначально установлено в generate_authorize_url.Итак, после восстановления токена с помощью вызова

token = gdata.gauth.OAuth2Token(...)

вам просто нужно установить URI перенаправления:

token.redirect_uri = 'http://path/that/you/set'

Проблема II : значение по умолчанию redirect_uri неверно (точнее, устарело).

Поскольку вы вызывали generate_authorize_url без аргументов, использовалось значение по умолчанию для redirect_uri, которое в настоящее время oob.Что касается состояния OAuth 2.0 docs , то oob не входит в число поддерживаемых значений (оно устарело).

Если вы действительно используете Установленное приложение, вам потребуется вместо этогоустановите его на

token.redirect_uri = 'urn:ietf:wg:oauth:2.0:oob'

Кроме того, когда вы вызываете generate_authorize_url, чтобы получить начальный токен, вам нужно будет использовать его в качестве параметра ключевого слова

url = token.generate_authorize_url(redirect_uri='urn:ietf:wg:oauth:2.0:oob')

ПроблемаIII : вы звоните get_access_token с неправильным значением (также не указанным в вашем фрагменте кода).

Вы должны вызывать это с использованием строкового значения кода, который вы получилипосле авторизации или со словарем, который имеет 'code' в качестве ключа.

Это можно сделать с помощью следующего:

import atom.http_core

# Page the user is redirected to after authorizing
redirected_page = 'http://path/that/you/set?code=RANDOM-CODE'
uri = atom.http_core.ParseUri(redirected_page)

# uri.query is a dictionary with the query string as key, value pairs
token.get_access_token(uri.query)

Post Script : Автор патч также опубликовал сообщение в блоге об использовании патча.(Обратите внимание, что в сообщении есть опечатка, когда в функции generate_authorize_url используется ключевое слово redirect_url.

)
...