:
def security_requirements(logged_in=True,
roles=None):
def wrapper(f):
# Store the security attributes as a member of the function object
f.access_control = dict(logged_in=logged_in, roles=roles)
@functools.wraps(f)
def wrapped(*args, **kwargs):
access_result = _eval_access(logged_in, roles)
# Redirect the user to the appropriate page (Access denied/Login Required/Actual Page) based on the result
...
与此装饰器的前一版本唯一真正的区别是在函数对象中存储安全属性的行。这条线在装饰者内部是无用的。但是,现在我可以执行以下操作以从Jinja模板调用:
{% if can_access(func) %}
<li><a>...</a></li>
{% endif %}
can_access函数在Flask应用程序模块中定义。它接收到一个字符串,它必须将其转换为函数对象。它是通过调用app.view_functions
:
def can_access(func):
return auth.can_access(app.view_functions[func])
这个功能应该从神社模板直接调用。因此,它需要被添加到神社的全局:
app.jinja_env.globals.update(can_access=can_access)
最后,auth.can_access
:
def can_access(f):
if not hasattr(f, 'access_control'):
return True
# Use the access_control member set by the decorator
return _eval_access(**f.access_control) == AccessResult.ALLOWED
这种解决方案意味着,访问控制是在一个地方定义的 - 这是函数装饰。
是'security_requirements'你的装饰者?是否允许改变它? – twil
@twil - 是的,这是我的 – reish