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

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

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

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

маркеры доступа имеют ограниченный срок службы, и в некоторых случаях приложению требуется доступ к 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]
}

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

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

4 ответов


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

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

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

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

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

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


Итак, если вы уже приняли согласие без установки 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'
)

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


ответы, кажется, устарели с 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())

Если вы следуете этому руководству https://developers.google.com/identity/protocols/OAuth2WebServer и вы не можете получить маркер обновления, попробуйте добавить запрос='согласие' здесь:

authorization_url, state = flow.authorization_url(
    # Enable offline access so that you can refresh an access token without
    # re-prompting the user for permission. Recommended for web server apps.
    access_type='offline',
    prompt='consent',
    # Enable incremental authorization. Recommended as a best practice.
    include_granted_scopes='true')

здесь описано, почему это может случиться