GAE 通过 app.yaml、python 装饰器或 users.get_current_user 强制登录?

Posted

技术标签:

【中文标题】GAE 通过 app.yaml、python 装饰器或 users.get_current_user 强制登录?【英文标题】:GAE enforcing sign in by app.yaml, python decorators or users.get_current_user? 【发布时间】:2012-12-08 12:46:17 【问题描述】:

我在我的 app.yaml 配置文件中为 GAE 应用程序使用了“登录”选项。看起来像这样:

- url: /admin/.*
  script: myapp.app
  login: admin

- url: /.*
  script: myapp.app
  login: required

更新(bossylobster 的建议):我希望用户始终登录(未签名的用户不能做任何事情),我需要知道用户是谁。实际上,我需要 OAuth2 凭据才能与 Google API 进行通信(例如,我需要使用 Google Profiles API 获取一些用户信息,并使用 Google Calendar API 写入用户的日历)。最后,我需要一个管理员用户来执行一些操作(例如使用 Google Provisioning API 创建新域的用户)

我正在使用 google-api-client 库,并使用 oauth2 装饰器。然后,在我的 RequestHandlers 中,我有这个:

class MainHandler(webapp.RequestHandler):

  @decorator.oauth_aware
  def get(self):
    if decorator.has_credentials():
      # do something

    else:
      url = decorator.authorize_url()
      self.response.out.write(template.render('templates/index.html',
           'authorize_url': url))

最后,我读到了另一种方法:

user = users.get_current_user()
if user:
  # do something
else:
  greeting = ("<a href=\"%s\">Sign in or register</a>." %
    users.create_login_url("/"))

  self.response.out.write("<html><body>%s</body></html>" % greeting)

处理用户身份验证以满足我的需求的最佳方法是什么(请参阅更新)?

在此先感谢

【问题讨论】:

【参考方案1】:

我认为您可能会混淆 OAuth 2.0 装饰器与其他两种方法的作用。

OAuth 2.0 装饰器并非特定于您的应用程序,如果您想为您的用户获取 OAuth 2.0 凭据,然后使用这些凭据与 Google API 进行通信,则可以使用它。

另外两种是从 App Engine 设置的会话 cookie 中获取用户信息的简单方法。

如果你真的想要一个装饰器,你会使用login_required,记录在这里:https://developers.google.com/appengine/docs/python/tools/webapp/utilmodule

在指定app.yaml、检查users.get_current_user 是否为None 或在指定的处理程序上使用@login_required 之间没有一种最佳方法。

您想要使用的三个不同时间的粗略近似如下:

1) 如果您希望用户登录,但不需要知道具体用户,请在app.yaml 中使用login: required

2) 如果想了解用户,但如果用户未登录也有后备,请使用users.get_current_user 并根据用户调整您的行为,如果返回值是None

3) 如果您想了解用户并且始终有一个用户登录,请使用@login_required

更新:

(基于对需求的进一步解释。)由于您始终希望用户登录并始终希望他们获得 OAuth 2.0 凭据,因此您应该始终使用 decorator.oauth_required

关于使用 API,只有Google Calendar API 可以与google-api-python-client 库一起使用。 Google Apps Provisioning API 是 Google Data API,而日历 API 是 discovery-based API。

因此,您需要使用 gdata-python-client library 来使用 Provisioning API。您需要手动将 oauth2client.client.OAuth2Credentials object 转换为 gdata.gauth.OAuth2Token 对象,以便为任一对象使用相同的令牌。

使用OAuth2Decorator 时,您将能够通过decorator.credentials() 访问oauth2client.client.OAuth2Credentials 的实例。

第二次更新:

我最近added支持这个到gdata-python-client

from gdata.gauth import OAuth2TokenFromCredentials
auth_token = OAuth2TokenFromCredentials(decorator.credentials())
auth_token.authorize(client)

该实现允许两个令牌/凭据对象 decorator.credentials()auth_token 保持同步,无论您更改哪个对象的值。

【讨论】:

感谢您的快速回复!我总是希望我的用户登录并了解用户。所以,我想我应该使用 3)。但我还需要 OAuth2 凭据才能与 Google API 进行通信。我可以在同一方法中使用@login_required AND oAuth2 装饰器吗? 您应该更新您的问题以说明这一点。从你的问题来看,这一点都不清楚。 OAuth2Decorator 扩展了 users.get_current_user 行为,并随后在登录用户完成 OAuth 流程后为其存储 OAuth 2.0 凭据。 你是对的。我更新了问题,对我的需求进行了更详细的解释。 谢谢!所以我看到我的方式是正确的。我实际上正在使用您所说的库。现在对我来说“黑暗”部分是 OAuth2 转换。无论如何,您的回答是绝对正确和有帮助的。再次感谢! 如果您想询问有关转换的其他问题并指出我的问题,我很乐意为您提供帮助。

以上是关于GAE 通过 app.yaml、python 装饰器或 users.get_current_user 强制登录?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Flask-Restless 进行 GAE app.yaml 路由

GAE app.yaml:如何设置包含句点的环境变量?

为子域配置 GAE 应用程序 app.yaml

在构建期间使用 gsutil builder 获取 app.yaml 来保护 GAE 环境变量?

谷歌应用引擎 |蟒蛇 |应用程序.YAML

如何将我的 app.yaml 迁移到 2.7?