2010-07-21 49 views
6

我有一个cherrypy应用程序,并且我想启动一些视图,只允许某些用户查看它们,并将其他人发送到需要授权的页面。编写一个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参数?或者我需要为每个组单独装饰器?

+0

所有这些都是可能的,但是您使用的是什么样的身份验证系统。或计划使用? CherryPy有几个身份验证方法:http://www.cherrypy.org/wiki/BuiltinTools – Wolph 2010-07-21 19:12:50

+0

我不认为我想使用任何内置的东西。我们有一些我需要检查的自定义数据存储库,等等。 – Greg 2010-07-21 19:14:03

回答

4

好了,在这种情况下你的装饰会是这个样子:

# 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 
+2

@ functools.wraps做什么?这是建在樱桃? – Greg 2010-07-21 19:21:20

+0

另外,我想我只有当登录的东西成功时才返回f(* args,** kwargs)?另一方面,如果用户没有被授权,我会打电话给cherry.redirect而不是返回吗? – Greg 2010-07-21 19:23:50

+0

是的,正确的。 而'functools.wraps'是一个处理函数名称,文档和其他数据写入装饰器时自动复制的方法。这样,如果您对装饰方法执行“帮助(方法)”,您仍然可以获得原始文档。 – Wolph 2010-07-21 19:37:25

13

你真的不希望编写自定义装饰器的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. 你会记得像所有的内置工具一样添加一个'debug'参数。 ;)
  5. 通过选择不同的“点”,您的功能可以比自定义装饰器更早(或更晚,如果这是您需要的)运行。
  6. 如果需要,您的功能可以在多个钩点运行。
+0

我不确定这是否适用于我,因为这段代码使用了RoutesDispatcher(而不是?)这个expose装饰器。我不确定为什么这样做。 – Greg 2010-07-21 23:08:48

+0

您使用哪个调度程序并不是一个真正的问题:任何值得使用它的调度程序(包括路径一)都可以使用工具。 这个expose装饰器只不过是设置了'method.exposed = True'。同样,这对所有调度员都是必需的,并且不论工具是否工作。从马的嘴里拿出来:工具是CherryPy做到这一点的方法。 – fumanchu 2010-07-23 06:14:26

+0

提供的代码片段在哪里去? – 2016-12-05 05:07:28