关于Python(Pylons)中授权和重定向装饰器的帮助
我正在尝试写一个简单的装饰器,用来检查用户是否登录,如果没有登录,就把他引导到登录页面:
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 个回答
5
我对Pylons不太了解,但看起来你写的装饰器有些问题。
装饰器是一个可以被调用的东西,它必须返回一个可以被调用的东西。装饰器在函数定义的时候就会被调用,它应该返回一个可以被调用的东西(通常是一个函数),这个返回的东西会替代被装饰的函数。
在你的例子中,装饰器只有在用户认证通过的情况下,才会返回一个可以调用的东西,这个认证是在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
。(这被称为闭包)
虽然装饰器不复杂,但理解起来确实有点难。你可以在谷歌上搜索关于装饰器的教程,有很多资源可以帮助你更清楚地理解这个概念,远比Python的文档要清晰得多。