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

ens*_*are 1 python pylons redirect 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' )
Run Code Online (Sandbox Code Playgroud)

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

HTTPFound: 302 Found Content-Type: text/html; charset=UTF-8 Content-Length: 0 location: /login
Run Code Online (Sandbox Code Playgroud)

谢谢您帮忙!

Adr*_*son 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
Run Code Online (Sandbox Code Playgroud)

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

@authenticate
def index(self):
    return render('/index.mako' )
Run Code Online (Sandbox Code Playgroud)

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

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

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