我正在尝试编写一个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 。所以我想我可以以某种方式请求刷新令牌。
我很感激有关如何使其发挥作用的任何帮助。如果您需要更多信息,请告诉我。
答案 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描述了为什么会发生