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()
这就是示例来自谷歌文档。有趣的是存储。它是保存一些凭据数据的文件。
我的存储文件的内容:
{
"_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。所以我想我可以以某种方式请求刷新令牌。
我将不胜感激任何有关如何使其发挥作用的帮助。如果您需要更多信息,请告诉我。
I am trying to write a Django app which creates events in a specific Google calendar. So far I have been successful. There is only a little problem:
I don't know how to obtain a refresh token with the google python client.
The result is that after my token expires the app does not work and I have to create a new token. If I understand the documentation correct that's where the refresh token comes in.
Access tokens have a limited lifetime and, in some cases, an application needs access to a Google API beyond the lifetime of a single access token. When this is the case, your application can obtain what is called a refresh token. A refresh token allows your application to obtain new access tokens.
Google Documentation (see "Basic Steps", Section 4)
My code
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()
This is pretty much the example from the Google documentation. The interesting bit is the Storage. It's a file where some credential data is saved.
Content of my storage file:
{
"_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]
}
There should be a refresh token in there, but instead it's null. So I figure I can somehow request a refresh token.
I would appreciate any help on how I can get this to work. If you need more information, please tell me.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我不知道如何使用 Python 客户端或日历 API 执行此操作(我只是使用 ruby OAuth2 库来访问联系人 API),但我发现我需要向用户请求“离线”访问。
这是通过将值为“offline”的“access_type”参数添加到授权 URL(将用户重定向到单击“我希望允许此应用程序获取我的数据”的 URL)来完成的。
如果您这样做,当您向 google 请求访问令牌时,您会在 JSON 响应中获得一个刷新令牌。否则,您只能获得访问令牌(有效期为一小时)。
这个要求显然是最近添加的(并且可能没有很好的记录)。
您过去无需获得特定的“离线”权限即可获得刷新令牌。
希望这能为您指明正确的方向。
I don't know how to do this with the Python Client or the Calendar API (I'm just using a ruby OAuth2 library for access to the Contacts API), but I found I needed to request "offline" access from the user.
This is done by adding the an "access_type" parameter with the value "offline" to the authorization url (the one you redirect the user to to click "I want to allow this application to get at my data").
If you do this, you get a refresh_token back in your JSON response when you ask google for access tokens. Otherwise you only get the access token (which is valid for an hour).
This requirement was apparently added recently (and may not be wonderfully documented).
You used to get a refresh token without having to get specific "offline" permission.
Hope this points you in the right direction.
因此,如果您在未设置
access_type='offline'
的情况下已接受同意,则需要通过传递approval_prompt='force'
来强制用户同意您的应用的离线访问权限代码>.然后,您可以在获取刷新令牌后删除强制提示/将其设置为
auto
。So if you've already accepted consent without setting
access_type='offline'
, you need to force the user to consent to your app with offline access by also passingapproval_prompt='force'
.Then you can remove the force prompt/set it to
auto
after you get the refresh token.自 2017-06-16 起,答案似乎已被弃用。
approval_prompt
已弃用prompt=force
无效以下是一个有效示例:
The answers seems to be deprecated as of 2017-06-16.
approval_prompt
is deprecatedprompt=force
is not validHere is a working example:
如果您遵循本手册https://developers.google.com/identity/protocols/OAuth2WebServer并且您无法接收refresh_token,请尝试在此处添加prompt='consent':
这里描述了为什么它可以发生
If you follow this manual https://developers.google.com/identity/protocols/OAuth2WebServer and you can not receive refresh_token, try to add prompt='consent' here:
Here is described why it can happen