Google Calendar API v3 - 如何获取刷新令牌(Python)

时间:2011-12-17 18:21:21

标签: python google-calendar-api google-api-python-client

我正在尝试编写一个Django应用程序,该应用程序在特定的Google日历中创建事件。到目前为止,我已经成功了。只有一点问题:

我不知道如何使用google python客户端获取刷新令牌。

结果是,在我的令牌过期后,应用程序无效,我必须创建一个新令牌。如果我理解文档是正确的,那么刷新令牌就会出现。

  

访问令牌的生命周期有限,在某些情况下,应用程序需要在单个访问令牌的生命周期之外访问Google API。在这种情况下,您的应用程序可以获得所谓的刷新令牌。刷新令牌允许您的应用程序获取新的访问令牌。

     

Google Documentation(参见“基本步骤”,第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 个答案:

答案 0 :(得分:19)

我不知道如何使用Python客户端或Calendar API执行此操作(我只是使用ruby OAuth2库来访问Contacts API),但我发现我需要请求“离线”访问用户。

这是通过将“access_type”参数和值“offline”添加到授权URL(您将用户重定向到的那个点击“我希望允许此应用程序获取我的数据”)来完成的。 / p>

如果你这样做,当你向谷歌要求访问令牌时,你会在你的JSON响应中得到一个refresh_token。否则,您只能获得访问令牌(有效期为一小时)。

最近显然添加了这项要求(可能没有精彩的记录)。

您曾经获得刷新令牌而无需获得特定的“离线”权限。

希望这能指出你正确的方向。

答案 1 :(得分:14)

因此,如果您已经在未设置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

答案 2 :(得分:4)

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())

答案 3 :(得分:0)

如果您遵循本手册https://developers.google.com/identity/protocols/OAuth2WebServer,但没有收到 refresh_token ,请尝试在此处添加 prompt ='consent'

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')

Here描述了为什么会发生