Google Calendar API v3 - 如何获取刷新令牌(Python)
我正在尝试写一个Django应用程序,用来在特定的Google日历中创建事件。到目前为止,我已经成功了。现在只有一个小问题:
我不知道如何通过Google的Python客户端获取刷新令牌。
结果就是,当我的令牌过期后,应用就无法工作,我必须重新创建一个新的令牌。如果我理解文档没错,这就是刷新令牌的用武之地。
访问令牌的有效期是有限的,有时候,应用需要在一个访问令牌的有效期之外继续访问Google的API。这种情况下,你的应用可以获取一个叫做刷新令牌的东西。刷新令牌可以让你的应用获取新的访问令牌。
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 个回答
这个答案似乎在2017年6月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())
所以,如果你已经让用户同意使用你的应用,但没有设置 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
。
我不知道怎么用Python客户端或者日历API来做这个(我只是用一个Ruby的OAuth2库来访问联系人API),但我发现我需要向用户请求“离线”访问权限。
这可以通过在授权网址中添加一个“access_type”参数,并把它的值设为“offline”来实现(这个网址是你引导用户点击“我想允许这个应用访问我的数据”的地方)。
如果你这样做,当你向谷歌请求访问令牌时,你会在JSON响应中得到一个refresh_token。否则你只会得到一个访问令牌(这个令牌的有效期是一个小时)。
这个要求显然是最近才添加的(可能文档上没有很好地说明)。
以前你可以在不需要特别请求“离线”权限的情况下就得到一个refresh token。
希望这能给你指明方向。