Google 日历 API - invalid_grant:令牌已过期或撤销
我创建了一个 bash 脚本,它使用 gcalcli 连接到谷歌日历并列出事件。为此,我启用了 Google 日历的 API 并生成了一个 OAuth2 令牌,该令牌基本上是一个 .json 文件,其中包含访问令牌、刷新令牌、到期日期和其他信息。
我的脚本每小时连接到日历,获取所有事件并向我发送电子邮件。在该脚本中,我还监视令牌的到期时间,只是为了确保它是最新的并且不会出现任何连接问题。
在一周内,该令牌始终是最新的。每小时我都会收到电子邮件并检查令牌是否是最新的。但每隔 7 天的凌晨 01:00,令牌就会过期,我必须生成一个新的令牌。我看到的错误如下:
oauth2client.client.HttpAccessTokenRefreshError: invalid_grant: Token has been expired or revoked.
这是我在 23:00 收到的电子邮件 - 这是整个星期的正常情况,总是晚 1 小时
token expiry 26/03/2022-22:00:06
这是我收到的电子邮件>at 00:00 - 这里的时间没有意义。晚了1小时38分钟。
token expiry 26/03/2022-22:22:37
在 01:00 我收到此错误:
Traceback (most recent call last):
File "/usr/bin/gcalcli", line 11, in <module>
load_entry_point('gcalcli==4.3.0', 'console_scripts', 'gcalcli')()
File "/usr/lib/python3/dist-packages/gcalcli/cli.py", line 152, in main
gcal.AgendaQuery(start=parsed_args.start, end=parsed_args.end)
File "/usr/lib/python3/dist-packages/gcalcli/gcal.py", line 1238, in AgendaQuery
return self._display_queried_events(start, end)
File "/usr/lib/python3/dist-packages/gcalcli/gcal.py", line 1182, in _display_queried_events
event_list = self._search_for_events(start, end, search)
File "/usr/lib/python3/dist-packages/gcalcli/gcal.py", line 1129, in _search_for_events
events = self._retry_with_backoff(
File "/usr/lib/python3/dist-packages/gcalcli/gcal.py", line 112, in _retry_with_backoff
return method.execute()
File "/usr/lib/python3/dist-packages/googleapiclient/_helpers.py", line 130, in positional_wrapper
return wrapped(*args, **kwargs)
File "/usr/lib/python3/dist-packages/googleapiclient/http.py", line 849, in execute
resp, content = _retry_request(
File "/usr/lib/python3/dist-packages/googleapiclient/http.py", line 165, in _retry_request
resp, content = http.request(uri, method, *args, **kwargs)
File "/usr/lib/python3/dist-packages/oauth2client/transport.py", line 186, in new_request
credentials._refresh(orig_request_method)
File "/usr/lib/python3/dist-packages/oauth2client/client.py", line 761, in _refresh
self._do_refresh_request(http)
File "/usr/lib/python3/dist-packages/oauth2client/client.py", line 819, in _do_refresh_request
raise HttpAccessTokenRefreshError(error_msg, status=resp.status)
oauth2client.client.HttpAccessTokenRefreshError: invalid_grant: Token has been expired or revoked.
其中显示invalid_grant:令牌已过期或撤销
到目前为止我已尝试过什么来解决此问题?
- 在 Google 上,我将项目发布到生产环境,但这没有效果。
- 我没有达到任何 OAuth 速率限制,因为每天有 10,000 笔授权,
- 我每小时都会确认令牌是否刷新(直到 7 天过去)。
- 谷歌帐户的密码没有改变
- 刷新令牌每小时使用一次,所以它不会在一周内过期
- 没有令牌被撤销,只有我可以访问这个谷歌帐户
我怀疑这是谷歌API上的某个设置,但是我不知道还能尝试什么。
可能是什么原因导致了这里的问题?
I created a bash script that uses gcalcli to connect to a google calendar and list events. To do that I have enabled APIs for google calendar and generated an OAuth2 token which is basically a .json file containing an access token, a refresh token, expiry date and other information.
My script connects to the calendar every hour, picks up any events and sends me an email. In that script I also monitor the expiry of the token, just to make sure it's up to date and I wont have any connectivity issues.
For one week, that token was always up to date. Every hour I would get the email and checked that the token was current. But every 7 days at 01:00 o'clock in the morning the token expires and I have to generate a new one. The error I'm seeing is the following:
oauth2client.client.HttpAccessTokenRefreshError: invalid_grant: Token has been expired or revoked.
This is from the email I get at 23:00 - This is normal throughout the week, always 1 hour behind
token expiry 26/03/2022-22:00:06
And this is from the email I get at 00:00 - The time here doesn't make sense. It's 1 hour and 38 minutes behind.
token expiry 26/03/2022-22:22:37
And at 01:00 I get this error:
Traceback (most recent call last):
File "/usr/bin/gcalcli", line 11, in <module>
load_entry_point('gcalcli==4.3.0', 'console_scripts', 'gcalcli')()
File "/usr/lib/python3/dist-packages/gcalcli/cli.py", line 152, in main
gcal.AgendaQuery(start=parsed_args.start, end=parsed_args.end)
File "/usr/lib/python3/dist-packages/gcalcli/gcal.py", line 1238, in AgendaQuery
return self._display_queried_events(start, end)
File "/usr/lib/python3/dist-packages/gcalcli/gcal.py", line 1182, in _display_queried_events
event_list = self._search_for_events(start, end, search)
File "/usr/lib/python3/dist-packages/gcalcli/gcal.py", line 1129, in _search_for_events
events = self._retry_with_backoff(
File "/usr/lib/python3/dist-packages/gcalcli/gcal.py", line 112, in _retry_with_backoff
return method.execute()
File "/usr/lib/python3/dist-packages/googleapiclient/_helpers.py", line 130, in positional_wrapper
return wrapped(*args, **kwargs)
File "/usr/lib/python3/dist-packages/googleapiclient/http.py", line 849, in execute
resp, content = _retry_request(
File "/usr/lib/python3/dist-packages/googleapiclient/http.py", line 165, in _retry_request
resp, content = http.request(uri, method, *args, **kwargs)
File "/usr/lib/python3/dist-packages/oauth2client/transport.py", line 186, in new_request
credentials._refresh(orig_request_method)
File "/usr/lib/python3/dist-packages/oauth2client/client.py", line 761, in _refresh
self._do_refresh_request(http)
File "/usr/lib/python3/dist-packages/oauth2client/client.py", line 819, in _do_refresh_request
raise HttpAccessTokenRefreshError(error_msg, status=resp.status)
oauth2client.client.HttpAccessTokenRefreshError: invalid_grant: Token has been expired or revoked.
Which shows invalid_grant: Token has been expired or revoked
What have I tried so far to fix this?
- On Google I published the project to production, but that had no effect.
- I am not hitting any OAuth rate limits because there are 10,000 grants per day
- I am confirming every hour that the token is refreshed and it is (up until 7 days pass).
- The password of the google account has not changed
- The refresh token is used every hour so it shouldn't expire in a week
- No tokens were revoked, only I have access to this google account
I suspect this is a setting somewhere on google APIs, but I don't know what else to try.
What could be causing the issue here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
正如我在评论中所说,这对我来说似乎是一个错误。
在这里,您有两个选择:
如果您有 Google Workspace 帐户,请打开一个新的Google Workspace 支持案例,以获取专家的帮助。
在 Calendar API 组件中打开新问题并尝试在不使用任何外部库的情况下重现您的问题(在您的情况下 gcalcli)。
As I say in the comments, this seems like a bug to me.
From here you have two options:
If you have a Google Workspace account, open a new Google Workspace Support Case to get help from specialists.
Open a new Issue in the Calendar API component and try to reproduce your problem without the use of any external library (in your case gcalcli).
如果您查看文档 oauth2#expiration 您会发现它指出
当您的应用程序处于测试阶段时,刷新令牌的有效期仅为 7 天。之后,对应用程序的访问将被撤销,刷新令牌将自动过期。
解决方案是在 oauth 同意屏幕下的 Google 开发者控制台上将您的项目设置为生产环境。
If you check the documentation oauth2#expiration You will find that it states
While your app is in testing the refresh token is only good for seven days. After that the access to the app will be revoked and the refresh token will automatically expire.
The solution is to set your project into to production on Google developer console under the oauth consent screen.
为了让您为 google api 创建的令牌不受限制,您需要转到 gcp 并创建一个服务帐户并使用为其提供的密钥来验证您的请求:
1- 进入您的 gcp 项目
2- 启用日历 api
3- 创建 OAuth 并下载 json 令牌
4- 创建服务帐户并在服务帐户内创建新的 json 密钥,密钥必须是 json 文件,也下载它
5- 转到您想要通过您的日历访问的日历api 并在
与特定人员共享
上添加您之前创建的服务帐户电子邮件从现在开始,使用 oauth.json 和 key.json 来验证您的请求,这样您现在需要不再担心过期了。
To have no limite in the tokens you create for google api, you need to go to gcp and create a service account and use the key provided for it in order to authenticate your requests:
1- Go into your gcp project
2- Enable calendar api
3- Create OAuth and download the json token
4- Create a service Account and create a new json key inside the service account, the key must be a json file, download it as well
5- Go to your calendar you want to access through your api and on the
Share with specific people
add the service account email you previously createdFrom now on, use that oauth.json and the key.json to authenticate your requests, in that way you will now need to worry about expiration anymore.