4

这篇文章是如何在 GAE cron 作业中执行需要 OAuth 的操作?,我意识到我误用了@oauth_required来自OAuth2DecoratorFromClientSecrets.

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

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

这就是@oauth_required抽象的内容,它做得很好(目前我的应用程序“工作”:如果我触发刷新页面,我被要求授权访问我的 youtube 数据到我的应用程序,其余的如下)。但这不是我想要的!我的应用程序做了一些更简单的事情,即每天使用我的凭据创建一个 youtube 播放列表,而无需任何用户输入。因此,与上述 3 层协商相比,我想要:

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

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

  1. 经过几次搜索后,我了解到我想要做的是称为离线访问(强调我的,这几乎正是我的用例):
    “在某些情况下,当用户不存在时,您的应用程序可能需要访问 Google API。这方面的示例包括备份服务和应用程序,它们恰好在星期一早上 8 点发布博客。这种访问方式称为离线,Web 服务器应用程序可能会请求用户离线访问。正常和默认的访问方式称为在线。 " ...
    → 所以我应该继续做我现在正在做的事情,继续请求访问我的 YouTube 帐户,但是使用type_access=offline标志来获取令牌,并将其保留/用于后续请求。

  2. 离线访问和 使用刷新令牌部分完全有意义,但停留在一般 HTTP 级别。作为一个新手,我不知道如何将这些原则集成到我的 Python 代码中,也没有找到任何示例 Python 代码......
    → 谁能帮我提供一个 Python 示例来说明如何以及在何处使用这面旗帜?

  3. ......尤其是在学习之后oauth2client.appengine.OAuth2Decorator.oauth_required,我仍然不确定是否可以将其弯曲到我的情况下,或者我是否应该做自己的事情。
    → 你怎么看?

谢谢你的时间; 如果需要,我也会在 irc://irc.freenode.net/#appengine 作为ronj.

4

1 回答 1

9

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

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

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

一旦您拥有这些凭证对象之一,您就可以使用它来授权一个 HTTP 对象来调用 APIS:

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

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

如果您知道用户 ID,则可以按照如何在 GAE 任务队列中执行需要 OAuth 的操作中credentials所述从数据存储中检索用户 ID。:

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,并且不需要不和谐的对话框。

于 2013-06-03T18:16:27.110 回答