如何在 GAE/Python 上进行“access_type=offline"/仅限服务器的 OAuth2 操作? [英] How to make 'access_type=offline' / server-only OAuth2 operations on GAE/Python?

查看:27
本文介绍了如何在 GAE/Python 上进行“access_type=offline"/仅限服务器的 OAuth2 操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

This post is a followup to How to do OAuth-requiring operations in a GAE cron job?, where I realized I'm mis-using the @oauth_required decorator from OAuth2DecoratorFromClientSecrets.

OAuth 2.0 说明中所述介绍,Oauth 2.0 解决了以下问题:

As described by the OAuth 2.0 explained presentation, Oauth 2.0 solves the problem of:

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

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

That's what @oauth_required abstracts, and it does it well (currently my app "works": if I trigger the refresh page, I'm being asked to authorize access to my youtube data to my app, and the rest follows). But that's not what I want! My app does something simpler, which is creating a youtube playlist every day with my credentials and without any user input. So to compare to the above 3-tier negociation, I want:

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

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

But I still need help to do that; here is my current state:

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

  1. After a few searches I learned that what I want to do is called Offline Access (emphasis mine, which is almost exactly my use case):
    "In some cases, your application may need to access a Google API when the user is not present. Examples of this include backup services and applications that make blogger posts exactly at 8am on Monday morning. This style of access is called offline, and web server applications may request offline access from a user. The normal and default style of access is called online."...
    → So I should keep doing what I'm doing right now, keep requesting access to my YouTube account, but do it using the type_access=offline flag to get a token, and persist/use it for subsequent requests.

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

The Offline Access and Using a Refresh Token sections make total sense, but stay at a general HTTP level. Being still a newbie, I don't see how to integrate those principles into my Python code, and I didn't find any sample Python code around....
→ Could anyone help me with one Python example illustrating how and where to use this flag?

... 特别是,在研究了 oauth2client.appengine.OAuth2Decorator.oauth_required 之后,我仍然不确定我是否可以将其弯曲到我的情况,或者我是否应该这样做我自己的东西.
→你怎么看?

... and in particular, after studying oauth2client.appengine.OAuth2Decorator.oauth_required, I'm still not sure if I can bend it to my case, or if I should do my own thing.
→ What do you think?

感谢您的时间;如果需要,我也会以 ronj 的身份在 irc://irc.freenode.net/#appengine 上闲逛.

Thanks for your time; if needed I'm also hanging out on irc://irc.freenode.net/#appengine as ronj.

推荐答案

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

Offline access is the default when retrieving tokens; you may have noticed this in the OAuth dialog that comes up:

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

Perform these operations when I'm not using the application

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

When your user accepts the OAuth dialog in a method decorated with decorator.oauth_required the credentials for that user will be stored in the datastore, including the refresh token.

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

Once you have one of these credentials objects, you can use it so authorize an HTTP object for calling APIS:

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

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

and once authorized, it will do all the work for you. So if the access_token is expired, the first API response will be a 401 and so the credentials object will use the refresh_token to get a new access_token and make the request again.

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

If you know the user ID, you can retrieve the credentials from the datastore as described in How to do OAuth-requiring operations in a GAE Task Queue?:

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

注意/问题:

如果用户已授权您的客户端 ID,那么您随后为这些用户执行 OAuth 时,他们将看不到 OAuth 对话框,您也不会获得刷新令牌.刷新令牌可以在通过 OAuth 对话框时提供,但由于用户已经授权您的客户端 ID,规范假设您已经拥有刷新令牌.

Note/Gotcha:

If a user has already authorized your client ID, the subsequent times you perform OAuth for these users they will not see the OAuth dialog and you won't be given a refresh token. A refresh token can only be given if they go through the OAuth dialog, but since the user had already authorized your client ID, the spec assumes you would already have a refresh token around.

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

This often comes up when developers are testing OAuth, since they will go through the flow multiple times with a test account and after accepting the 2nd, 3rd, 4th, ... times, they never see the refresh token. A simple way around this is to use approval_prompt=force as an argument to the OAuth2Decorator constructor. This will force the OAuth dialog to appear every time you perform OAuth for a user.

但是,这不会导致每次为给定用户提供请求时都显示对话框;这将是一个糟糕的用户体验.相反,请求中的 SACSID cookie 可用于(由客户端库和某些 App Engine 库使用)来确定当前用户是谁.一旦库知道当前用户,它就可以从数据存储中为该用户获取您现有的存储令牌/凭据,并且不需要不和谐的对话.

However, this will not cause the dialog to show up every time a request is served for a given user; this would be a TERRIBLE user experience. Instead, the SACSID cookie from the request can be used (by the client library and some App Engine libraries) to determine who the current user is. Once the the library knows that current user, it can get your existing stored token/credentials for that user from the datastore and no jarring dialog will be needed.

这篇关于如何在 GAE/Python 上进行“access_type=offline"/仅限服务器的 OAuth2 操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆