这篇文章是 How to do OAuth-requiring operations in a GAE cron job? 的后续内容,我发现自己错误地使用了来自@oauth_required
的{{1}}装饰器。
如OAuth 2.0 explained演示文稿所述,Oauth 2.0解决了以下问题:
这就是OAuth2DecoratorFromClientSecrets
抽象的内容,它做得很好(目前我的应用程序“有效”:如果我触发刷新页面,我会被要求授权访问我的YouTube数据到我的应用程序,以及休息如下)。但那不是我想要的!我的应用程序做了一些更简单的操作,即每天使用我的凭据和创建一个youtube播放列表,而无需任何用户输入。因此,为了与上述三层协会进行比较,我想:
但我仍然需要帮助才能做到这一点;这是我目前的状态:
经过几次搜索,我了解到我想做的事情被称为Offline Access(强调我的,这几乎就是我的用例):
“在某些情况下,当用户不在场时,您的应用可能需要访问Google API。例如,备份服务和应用在周一早上8点准确发布博客帖子。这种访问方式称为脱机,Web服务器应用程序可以请求用户进行脱机访问。正常和默认访问方式称为在线。“ ...
→所以我应该继续做我现在正在做的事情,继续请求访问我的YouTube帐户,但是使用@oauth_required
标志来获取令牌,并将其用于后续请求。
Offline Access 和使用刷新令牌部分完全合理,但保持一般的HTTP级别。作为一个新手,我不知道如何将这些原则集成到我的Python代码中,我没有找到任何示例Python代码.... →任何人都可以帮我一个Python示例,说明如何以及在何处使用此标志?
...特别是在研究type_access=offline
之后,我仍然不确定我是否能够将其归结为我的情况,或者我是否应该做自己的事情。
→您怎么看?
谢谢你的时间;如果需要的话我也会在{ic://irc.freenode.net/#appengine oauth2client.appengine.OAuth2Decorator.oauth_required
上闲逛。
答案 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
,并且不需要任何刺耳的对话框。