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 路由