以下是我想要组合的两个装饰器,因为它们非常相似,不同之处在于如何处理未经过身份验证的用户。我更愿意拥有一个可以用参数调用的装饰器。
# Authentication decorator for routes
# Will redirect to the login page if not authenticated
def requireAuthentication(fn):
def decorator(**kwargs):
# Is user logged on?
if "user" in request.session:
return fn(**kwargs)
# No, redirect to login page
else:
redirect('/login?url={0}{1}'.format(request.path, ("?" + request.query_string if request.query_string else '')))
return decorator
# Authentication decorator for routes
# Will return an error message (in JSON) if not authenticated
def requireAuthenticationJSON(fn):
def decorator(**kwargs):
# Is user logged on?
if "user" in request.session:
return fn(**kwargs)
# No, return error
else:
return {
"exception": "NotAuthorized",
"error" : "You are not authorized, please log on"
}
return decorator
目前我正在将这些装饰器用于特定路线,例如
@get('/day/')
@helpers.requireAuthentication
def day():
...
@get('/night/')
@helpers.requireAuthenticationJSON
def night():
...
我更喜欢这个:
@get('/day/')
@helpers.requireAuthentication()
def day():
...
@get('/night/')
@helpers.requireAuthentication(json = True)
def night():
...
我使用Bottle框架在python 3.3上。有可能做我想要的吗?怎么样?
答案 0 :(得分:2)
只需添加另一个包装器即可捕获json
参数:
def requireAuthentication(json=False):
def decorator(fn):
def wrapper(**kwargs):
# Is user logged on?
if "user" in request.session:
return fn(**kwargs)
# No, return error
if json:
return {
"exception": "NotAuthorized",
"error" : "You are not authorized, please log on"
}
redirect('/login?url={0}{1}'.format(request.path, ("?" + request.query_string if request.query_string else '')))
return wrapper
return decorator
我已将您的原始requireAuthentication
功能重命名为decorator
(因为这是该功能所做的,它修饰了fn
)并将旧decorator
重命名为{{ 1}},通常的惯例。
无论你在后放置,wrapper
是一个表达式,首先进行评估以找到实际的装饰器函数。 @
表示您要调用@helpers.requireAuthentication()
,然后将返回值用作requireAuthentication
行适用的函数的实际装饰器。
答案 1 :(得分:1)
您可以为这两个装饰器创建包装器:
def requireAuthentication(json=False):
if json:
return helpers.requireAuthenticationJSON
else:
return helpers.requireAuthentication
或者
import functools
# Authentication decorator for routes
# Will redirect to the login page if not authenticated
def requireAuthentication(json=False):
def requireAuthentication(fn):
@functools.wraps(fn)
def decorator(*args, **kwargs):
# Is user logged on?
if "user" in request.session:
return fn(*args, **kwargs)
if json:
return {
"exception": "NotAuthorized",
"error" : "You are not authorized, please log on"
}
return redirect('/login?url={0}{1}'.format(request.path,
("?" + request.query_string if request.query_string else '')))
return decorator
return requireAuthentication