帮助python(pylons)中的授权和重定向装饰器

时间:2010-04-27 18:50:00

标签: python redirect pylons decorator

我正在尝试编写一个简单的装饰器来检查用户的身份验证,如果他/她未经过身份验证,则会重定向到登录页面:

def authenticate(f):
    try:
        if user['authenticated'] is True:
            return f
    except:
        redirect_to(controller='login', action='index')

class IndexController(BaseController):
    @authenticate
    def index(self):
        return render('/index.mako' )

但这种方法不起作用。用户通过身份验证后,一切都很好。但是当用户未经过身份验证时,redirect_to()不起作用,我收到此错误:

HTTPFound: 302 Found Content-Type: text/html; charset=UTF-8 Content-Length: 0 location: /login

感谢您的帮助!

1 个答案:

答案 0 :(得分:5)

我不知道挂架,但看起来你写装饰器的方式并不好。

装饰器是可调用的,必须返回可调用的。装饰器在定义函数时被调用,它应该返回一个可调用的(通常是一个函数),它将被调用来代替被装饰的函数。

在您的示例中,只有在定义了index()函数的情况下对用户进行了身份验证时,装饰器才会返回可调用对象。

尝试以这种方式重写:

def authenticate(func):
    def call(*args, **kwargs):
        if user['authenticated'] is True:
            return func(*args,**kwargs)
        else:
            return redirect_to(controller='login', action='index')
    return call

这里,authenticate()定义了一个内部函数,它返回代替它所装饰的函数。现在当你使用这个装饰器装饰一个函数时:

@authenticate
def index(self):
    return render('/index.mako' )

这意味着每次调用index()时,实际上都在调用装饰器中声明的内部函数。

你应该注意:由于在python中定义函数的方式,装饰器返回的函数对象仍然记住定义它的函数的参数值。 call()仍然知道调用装饰器时传递的参数func。 (这称为闭包)

装饰器很难理解,尽管它们并不复杂。你应该在google上搜索关于装饰器的教程:有很多它们对这个概念有很好的理解,远比python文档更清晰。