Google Calendar API v3 - Как получить токен обновления (Python)

Я пытаюсь написать приложение Django, которое создает события в определенном календаре Google. До сих пор я был успешным. Существует только небольшая проблема:

Я не знаю, как получить токен обновления с клиентом python google.

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

Ленты доступа имеют ограниченный срок службы, и в некоторых случаях приложение нуждается в доступе к API Google за пределы срока службы одного токена доступа. В этом случае ваше приложение может получить то, что называется токеном обновления. Ток обновления позволяет вашему приложению получать новые токены доступа.

Документация Google (см. "Основные шаги", раздел 4)

Мой код

import gflags
import httplib2

from apiclient.discovery import build
from oauth2client.file import Storage
from oauth2client.client import OAuth2WebServerFlow
from oauth2client.tools import run

FLAGS = gflags.FLAGS

FLOW = OAuth2WebServerFlow(
    client_id=GOOGLE_API_CLIENT_ID,
    client_secret=GOOGLE_API_CLIENT_SECRET,
    scope=GOOGLE_API_CALENDAR_SCOPE,
    user_agent=GOOGLE_API_USER_AGENT)

storage = Storage(GOOGLE_API_CREDENTIAL_PATH)
credentials = storage.get()
if credentials is None or credentials.invalid == True:
  credentials = run(FLOW, storage)

http = httplib2.Http()
http = credentials.authorize(http)

service = build(serviceName='calendar', version='v3', http=http,
   developerKey=GOOGLE_API_DEVELOPER_KEY)

event = {
    [... Dictionary with all the necessary data here ...]
}

created_event = service.events().insert(calendarId=GOOGLE_API_CALENDAR_ID, body=event).execute()

Это в значительной степени пример из документации Google. Интересный бит - это хранилище. Это файл, в котором сохранены некоторые учетные данные.

Содержимое моего файла хранилища:

{
    "_module": "oauth2client.client", 
    "_class": "OAuth2Credentials", 
    "access_token": [redacted], 
    "token_uri": "https://accounts.google.com/o/oauth2/token", 
    "invalid": true, 
    "client_id": [redacted], 
    "client_secret": [redacted], 
    "token_expiry": "2011-12-17T16:44:15Z", 
    "refresh_token": null, 
    "user_agent": [redacted]
}

Там должен быть токен обновления, но вместо этого он равен нулю. Поэтому я полагаю, что могу как-то запросить токен обновления.

Я был бы признателен за любую помощь в том, как я могу заставить это работать. Если вам нужна дополнительная информация, сообщите мне.

Ответы

Ответ 1

Я не знаю, как это сделать с помощью Python Client или API календаря (я просто использую рубиновую библиотеку OAuth2 для доступа к API контактов), но я обнаружил, что мне нужно запросить "автономный" доступ из пользователя.

Это делается путем добавления параметра "access_type" со значением "offline" к URL-адресу авторизации (тот, который вы перенаправляете пользователю, чтобы щелкнуть "Я хочу разрешить этому приложению получать мои данные" ).

Если вы сделаете это, вы получите refresh_token в ответном ответе JSON, когда попросите google для доступа к токенам. В противном случае вы получаете только токен доступа (который действителен в течение часа).

Это требование, по-видимому, было добавлено недавно (и, возможно, это не чудесно задокументировано).

Вы использовали для получения токена обновления без необходимости получения определенного "автономного" разрешения.

Надеюсь, это указывает на то, что вы в правильном направлении.

Ответ 2

Итак, если вы уже приняли согласие без установки access_type='offline', вам нужно заставить пользователя согласиться с вашим приложением с автономным доступом, также пропустив approval_prompt='force'.

self.flow = OAuth2WebServerFlow(
    client_id=self.client_id,
    client_secret=self.client_secret,
    scope=self.SCOPE,
    user_agent=user_agent,
    redirect_uri='urn:ietf:wg:oauth:2.0:oob',
    access_type='offline', # This is the default
    approval_prompt='force'
)

Затем вы можете удалить приглашение силы/установить его на auto после получения токена обновления.

Ответ 3

Ответы, кажется, устарели от 2017-06-16.

  • approval_prompt устарел
  • prompt=force недействителен

Вот рабочий пример:

from oauth2client.client import OAuth2WebServerFlow

flow = OAuth2WebServerFlow(
    client_id=CLIEN_ID,
    client_secret=CLIENT_SECRET,
    scope=SCOPES,
    redirect_uri='http://localhost/gdrive_auth',
    access_type='offline',
    prompt='consent',
)

print(flow.step1_get_authorize_url())