如何在GAE / Python上进行'access_type = offline'/仅服务器OAuth2操作?

时间:2013-06-03 15:57:27

标签: python google-app-engine google-api oauth-2.0 google-api-python-client

这篇文章是 How to do OAuth-requiring operations in a GAE cron job? 的后续内容,我发现自己错误地使用了来自@oauth_required的{​​{1}}装饰器。

OAuth 2.0 explained演示文稿所述,Oauth 2.0解决了以下问题:

  • 构建服务 ...
  • ...由用户 ...
  • 访问
  • ... 并从第三方访问用户的数据

这就是OAuth2DecoratorFromClientSecrets抽象的内容,它做得很好(目前我的应用程序“有效”:如果我触发刷新页面,我会被要求授权访问我的YouTube数据到我的应用程序,以及休息如下)。但那不是我想要的!我的应用程序做了一些更简单的操作,即每天使用我的凭据和创建一个youtube播放列表,而无需任何用户输入。因此,为了与上述三层协会进行比较,我想:

  • 服务
  • ...由用户
  • 访问
  • ... 但仅访问“服务器拥有的”YouTube播放列表数据。 我不想访问用户的YouTube数据,我只想修改播放列表I(即我/服务器持久保存的用户ID)拥有。

但我仍然需要帮助才能做到这一点;这是我目前的状态:

  1. 经过几次搜索,我了解到我想做的事情被称为Offline Access(强调我的,这几乎就是我的用例):
    “在某些情况下,当用户不在场时,您的应用可能需要访问Google API。例如,备份服务和应用在周一早上8点准确发布博客帖子。这种访问方式称为脱机,Web服务器应用程序可以请求用户进行脱机访问。正常和默认访问方式称为在线。“ ...
    →所以我应该继续做我现在正在做的事情,继续请求访问我的YouTube帐户,但是使用@oauth_required标志来获取令牌,并将其用于后续请求。

  2. Offline Access 使用刷新令牌部分完全合理,但保持一般的HTTP级别。作为一个新手,我不知道如何将这些原则集成到我的Python代码中,我没有找到任何示例Python代码.... →任何人都可以帮我一个Python示例,说明如何以及在何处使用此标志?

  3. ...特别是在研究type_access=offline之后,我仍然不确定我是否能够将其归结为我的情况,或者我是否应该做自己的事情。
    →您怎么看?

  4. 谢谢你的时间;如果需要的话我也会在{ic://irc.freenode.net/#appengine oauth2client.appengine.OAuth2Decorator.oauth_required上闲逛。

1 个答案:

答案 0 :(得分:8)

在检索令牌时,离线访问是default;您可能已经在出现的OAuth对话框中注意到了这一点:

  

当我不使用应用程序时执行这些操作

当您的用户在装有decorator.oauth_required的方法中接受OAuth对话框时,该用户的凭据将存储在数据存储区中,包括刷新令牌。

一旦您拥有其中一个凭据对象,就可以使用它来授权HTTP对象来调用APIS:

import httplib2
http = credentials.authorize(httplib2.Http())

一旦获得授权,它将为您完成所有工作。因此,如果access_token已过期,则第一个API响应将为401,因此credentials对象将使用refresh_token获取新的access_token和再次提出请求。

如果您知道用户ID,则可以按照How to do OAuth-requiring operations in a GAE Task Queue?中的说明从数据存储中检索credentials

from oauth2client.appengine import CredentialsModel
from oauth2client.appengine import StorageByKeyName
credentials = StorageByKeyName(
     CredentialsModel, user_id, 'credentials').get()

注意/疑难杂症:

如果用户已经授权您的客户端ID,则以后您为这些用户执行OAuth时,他们将看不到OAuth对话框,并且您将不会获得刷新令牌。如果刷新令牌通过OAuth对话框,则只能 ,但由于用户已经授权您的客户端ID,因此该规范假设您已经拥有刷新令牌。

当开发人员测试OAuth时,通常会出现这种情况,因为他们将使用测试帐户多次访问流程,并且在接受第2,第3,第4 ......次之后,他们永远不会看到刷新令牌。解决此问题的一种简单方法是使用approval_prompt=force作为OAuth2Decorator构造函数的参数。这将强制每次为用户执行OAuth时都会显示OAuth对话框。

但是,不会导致每次为给定用户提供请求时都会显示对话框;这将是可怕的用户体验。相反,可以使用来自请求的SACSID cookie(由客户端库和一些App Engine库)来确定当前用户是谁。一旦图书馆知道当前用户,它就可以从数据存储中获取该用户现有的存储令牌/ credentials,并且不需要任何刺耳的对话框。