6

这篇文章是How to make 'access_type=offline' / server-only OAuth2 operations on GAE/Python的后续文章。该http = credentials.authorize(httplib2.Http())部分在测试时不再失败,但在 GAE 的 cron 运行时它似乎仍然失败,它无法刷新我的access_token

  1. 我可以通过调用来手动运行我的工作/fetch,比如说在 11:45。
  2. 然后在 11:55立即安排/cronfetch工作,没有任何access_token问题。
  3. 但是,今天早上我醒来发现同样 /cronfetch的任务(除了时间相同,我的非测试日常任务是在 01:00 时)失败了:

    I 2013-06-10 05:53:51.324 make: Got type <class 'google.appengine.api.datastore_types.Blob'>
    I 2013-06-10 05:53:51.325 validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
    I 2013-06-10 05:53:51.327 URL being requested: https://www.googleapis.com/youtube/v3/playlists?alt=json&part=snippet%2Cstatus
    I 2013-06-10 05:53:51.397 Refreshing due to a 401
    I 2013-06-10 05:53:51.420 make: Got type <class 'google.appengine.api.datastore_types.Blob'>
    I 2013-06-10 05:53:51.421 validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
    I 2013-06-10 05:53:51.421 Refreshing access_token
    I 2013-06-10 05:53:51.458 Failed to retrieve access token: { "error" : "invalid_grant" }
    I 2013-06-10 05:53:51.468 make: Got type <class 'google.appengine.api.datastore_types.Blob'>
    I 2013-06-10 05:53:51.468 validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
    I 2013-06-10 05:53:51.471 validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
    I 2013-06-10 05:53:51.471 get: Got type <class 'oauth2client.appengine.CredentialsModel'>
    E 2013-06-10 05:53:51.480 invalid_grant Traceback (most recent call last): File "/python27_runtime/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1535, in
    

这个在令牌刷新邮件列表消息(+ SO post 1SO post 2SO post 3 )上出现“invalid_grant”错误看起来与我的问题相似,但它似乎与令牌有关。在我的情况下,我只使用 default ,并且在初始访问请求中 看到“在我不使用应用程序时执行这些操作” 。access_type=onlineaccess_type=offline

我刚刚在 08:25 重新安排了一次 cron 运行(注意不要启动手动运行),其中包含我为您提交给 GitHub 的调试打印语句。create_playlist这是我得到的,它相似但不完全相同(注意最后几行似乎排序不正确,在读取所有源之前我绝对不会做 OAuth2 的东西)。所以忽略倾斜的顺序(GAE 日志记录工件?),看来我的http = credentials.authorize(Http())调用create_playlist(self),目前在第 144 行是错误的:

    ...
    E 2013-06-10 08:26:12.817 http://www.onedayonemusic.com/page/2/ : found embeds ['80wWl_s-HuQ', 'kb1Nu75l1vA', 'kb1Nu75l1vA', 'RTWcNRQtkwE', 'RTWcNRQtkwE', 'ZtDXezAhes8', 'ZtDXezAhes8', 'cFGxNJhKK9c', 'cFGxNJhKK9c'
    I 2013-06-10 08:26:14.019 make: Got type <class 'google.appengine.api.datastore_types.Blob'>
    I 2013-06-10 08:26:14.020 validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
    I 2013-06-10 08:26:14.022 URL being requested: https://www.googleapis.com/youtube/v3/playlists?alt=json&part=snippet%2Cstatus
    I 2013-06-10 08:26:14.100 Refreshing due to a 401
    I 2013-06-10 08:26:14.105 make: Got type <class 'google.appengine.api.datastore_types.Blob'>
    I 2013-06-10 08:26:14.106 validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
    I 2013-06-10 08:26:14.106 Refreshing access_token
    E 2013-06-10 08:26:18.994 Deadline exceeded while waiting for HTTP response from URL: https://accounts.google.com/o/oauth2/token Traceback (most recent call last): File "/pyt
    E 2013-06-10 08:26:18.996 http://www.onedayonemusic.com/page/3/ : found embeds ['80wWl_s-HuQ', '6VNu2MLdE0c', '6VNu2MLdE0c', 'YwQilKbK9Mk', 'YwQilKbK9Mk', 'KYdB3rectmc', 'KYdB3
    E 2013-06-10 08:26:18.996 crawl_videos end
    E 2013-06-10 08:26:18.996 create_playlist start
    E 2013-06-10 08:26:18.996 create_playlist got creds
    E 2013-06-10 08:26:18.996 create_playlist authorized creds

→ 为什么 cron 作业在手动运行 5 分钟后工作,但在 6 小时后失败?我认为刷新令牌永不过期。我究竟做错了什么?

请注意,这是我的第一个 GAE 工作,也是我的第二个 Python 程序,非常欢迎一般的代码审查/建议,但请保持温和 :)

代码在GitHub 上,我的实例可以在dailygrooves.org上找到。谢谢你的帮助!

4

1 回答 1

4

invalid_grant当刷新令牌不能用于从当前用户获取新的访问令牌时,返回一个。这发生在您身上,因为存储的Credentials对象有一个空刷新令牌,即

>>> credentials.refresh_token is None
True

如何在 GAE/Python 上进行“access_type=offline”/仅服务器 OAuth2 操作中的注释中所述?:

如果用户已经授权了您的客户端 ID,那么您在随后为这些用户执行 OAuth 时,他们将不会看到 OAuth 对话框,并且您不会获得刷新令牌。

您需要确保您Credentials使用有效的刷新令牌存储,并且最简单的方法是,正如您在上一个问题以及您链接到的所有 3 个问题中提到的那样,approval_prompt=force在创建您的OAuth2WebServerFlowOAuth2Decorator对象时使用(无论您使用的是哪个)。

于 2013-06-10T15:54:17.203 回答