【问题标题】:Writing a CherryPy Decorator for Authorization为授权编写 CherryPy 装饰器
【发布时间】:2011-03-19 04:28:32
【问题描述】:

我有一个cherrypy 应用程序,在某些视图上我想开始只允许某些用户查看它们,并将其他任何人发送到需要授权的页面。

有没有办法使用自定义装饰器来做到这一点?我认为这将是最优雅的选择。

这是我想做的一个基本示例:

class MyApp:
    @authorization_required
    def view_page1(self,appID):
        ... do some stuff ...
        return html

def authorization_required(func):
    #what do I put here?

在作为装饰器调用时,authorization_required 函数是否也可以接受诸如 allow_group1、allow_group2 之类的参数?还是每个组都需要一个单独的装饰器?

【问题讨论】:

  • 所有这些都是可能的,但是您使用的是哪种身份验证系统。还是打算使用? CherryPy 内置了几种身份验证方法:cherrypy.org/wiki/BuiltinTools
  • 我想我不想使用任何内置的东西。我们有一些我需要检查的自定义数据存储,等等。

标签: python permissions authorization decorator cherrypy


【解决方案1】:

好的,在这种情况下,你的装饰器看起来像这样:

# without any parameters
def authentication_required(f):
    @functools.wraps(f)
    def _authentication_required(*args, **kwargs):
        # Do you login stuff here
        return f(*args, **kwargs)
    return _authentication_required

# With parameters
def authentication_required(*allowed_groups):
    def _authentication_required(f):
        @functools.wraps(f)
        def __authentication_required(*args, **kwargs):
            # Do you login stuff here
            return f(*args, **kwargs)
        return __authentication_required
    return _authentication_required

【讨论】:

  • @functools.wraps 有什么作用?这是cherrypy内置的吗?
  • 另外,我想我只有在登录成功时才返回 f(*args, **kwargs) ?另一方面,如果用户未被授权,我会调用cherry.redirect而不是返回吗?
  • 是的,正确的。而functools.wraps 是一种在编写装饰器时处理函数名、文档和其他数据的自动复制的方法。这样,如果您在装饰方法上执行 help(method),您仍然可以获得原始文档。
  • 我使用的是 Python 2.4,所以我没有 functools。有解决办法吗?
  • 您可以简单地将__name__、__module__ 和__doc__ 属性复制到您的函数中。不过,fumanchu 似乎有一个更合适的解决方案。
【解决方案2】:

您真的不想为 CherryPy 编写自定义装饰器。相反,您想编写一个新工具:

def myauth(allowed_groups=None, debug=False):
    # Do your auth here...
    authlib.auth(...)
cherrypy.tools.myauth = cherrypy.Tool("on_start_resource", myauth)

更多讨论请参见http://docs.cherrypy.org/en/latest/extend.html#tools。与编写自定义装饰器相比,这有几个好处:

  1. 您可以从工具中免费获得装饰器:@cherrypy.tools.myauth(allowed_groups=['me']),它已经知道如何在同一函数上不破坏cherrypy.exposed。
  2. 您可以为每个处理程序(使用装饰器)、每个控制器树(通过_cp_config)或每个 URI 树(在配置文件或字典中)应用工具。您甚至可以混合它们并通过装饰器提供基本功能,然后在配置文件中覆盖它们的行为。
  3. 如果配置文件关闭了您的功能,您无需支付调用装饰器函数来查看它是否关闭的性能损失。
  4. 您会记得像所有内置工具一样添加一个“调试”参数。 ;)
  5. 通过选择不同的“点”,您的功能可以比自定义装饰器更早(或更晚,如果您需要的话)运行。
  6. 如果需要,您的功能可以在多个挂钩点上运行。

【讨论】:

  • 我不确定这是否对我有用,因为此代码使用的是 RoutesDispatcher(而不是?)暴露装饰器。我不知道为什么会这样。
  • 您使用哪个调度程序并不是一个真正的问题:任何值得其盐分的调度程序(包括路线之一)都可以使用工具。暴露装饰器只是设置method.exposed = True。同样,这对所有调度程序都是必需的,并且与工具是否工作无关。从马嘴里拿出来:工具是在 CherryPy 中做到这一点的方法。
猜你喜欢
  • 2021-01-28
  • 1970-01-01
  • 2017-09-09
  • 2011-04-20
  • 2019-01-07
  • 2015-02-21
  • 1970-01-01
  • 2023-03-28
  • 2012-10-28
相关资源
最近更新 更多