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

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

问题描述

这篇文章是对 如何在GAE cron作业中执行OAuth需求操作? ,我意识到我错了 - 使用 @oauth_required 从 OAuth2DecoratorFromClientSecrets



的装饰器如 OAuth 2.0解释演示文稿,Oauth 2.0解决了以下问题:




  • 建立服务 ...

  • ...由用户 ...

  • ... 并从第三方访问用户数据



  • 这就是 @oauth_required 摘要,它做得很好(目前我的应用程序有效 :如果我触发刷新页面,我是贝ng要求授权将我的YouTube数据访问到我的应用程序,其余部分如下)。但那不是我想要的!我的应用程序做了一些简单的操作,每天用我的凭证和创建一个YouTube播放列表,而不需要任何用户输入。因此,为了与上面的三层关系进行比较,我想:


    • 服务

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


    但我仍然需要帮助;这里是我目前的状态:


    1. 经过几次搜索后,我了解到我想要做的事情叫做离线访问(强调我的,这几乎就是我的用例):

      在某些情况下,当用户不在时,您的应用可能需要访问Google API,例如备份服务和周一早上8点左右发布博客帖子的应用 。这种访问方式称为离线,Web服务器应用程序可以请求用户离线访问。正常和默认的访问方式称为在线。 ...

      →所以我应该继续做我现在正在做的事情,继续请求访问我的YouTube帐户,但是使用 type_access = offline 标志来获取令牌,并坚持/将其用于后续请求。

    2. Offline Access 使用刷新令牌部分总是有意义的,但保持在一般的HTTP级别。作为一名新手,我没有看到如何将这些原则集成到我的Python代码中,并且我没有发现任何Python代码示例....

      →任何人都可以用一个Python例子来说明如何以及在哪里使用这个标志?
    3. ...特别是在学习 oauth2client.appengine.OAuth2Decorator.oauth_required 之后,I'我仍然不确定自己是否可以屈服于自己的情况,或者如果我应该做我自己的事情。

      →你认为什么?


    感谢您的时间;如果需要的话,我也会在irc://irc.freenode.net/#appengine上作为 ronj 出现。

    解决方案

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


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


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



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

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

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

    如果您知道用户标识,则可以从数据存储中检索 credentials ,如如何在GAE Task Queue中执行OAuth-需要的操作? :来自oauth2client.appengine的

     从oauth2client.appengine导入CredentialsModel 
    导入StorageByKeyName
    凭据= StorageByKeyName(
    CredentialsModel,user_id,'credentials').get()



    如果用户已经授权了您的客户端ID,那么随后您为这些用户执行OAuth时,他们将不会看到OAuth对话框,并且您赢了没有给予刷新标记。如果刷新标记通过OAuth对话框,则只能指定 ,但由于用户已经授权了您的客户端ID,因此该规范假定您已经拥有刷新令牌。



    当开发人员测试OAuth时,通常会出现这种情况,因为他们将多次使用测试帐户进行流操作,并且在接受第2,3,4,...次后,他们从不请参阅刷新令牌。一个简单的方法是使用 approval_prompt = force 作为 OAuth2Decorator 构造函数的参数。这会强制OAuth对话框在您每次为用户执行OAuth时出现。



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


    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.

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

    • Building a service...
    • ... accessed by a user...
    • ... and accessing the user's data from a third party.

    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:

    • A service
    • ... accessed by users
    • ... but only accessing "server-owned" YouTube playlist data. I don't want any access to the user's YouTube data, I just want to modify a playlist I (i.e. me / a userid persisted by the server) own.

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

    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.

    2. 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?

    3. ... 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?

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

    解决方案

    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

    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.

    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())
    

    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.

    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()
    

    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.

    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.

    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天全站免登陆