虽然 Flask-Principal 是最受欢迎的插件,但它并不复杂,而且在我需要的大多数情况下它不起作用。我一直试图强迫它以我喜欢的方式工作,但我从未成功过。幸运的是,我找到了一个非常简单且轻量级的模块——权限:
用法
首先,您需要通过子类化定义自己的规则,Rule
然后覆盖check()
and deny()
:
# rules.py
from flask import session, flash, redirect, url_for
from permission import Rule
class UserRule(Rule):
def check(self):
"""Check if there is a user signed in."""
return 'user_id' in session
def deny(self):
"""When no user signed in, redirect to signin page."""
flash('Sign in first.')
return redirect(url_for('signin'))
Permission
然后通过子类化和覆盖来定义权限rule()
:
# permissions.py
from permission import Permission
from .rules import UserRule
class UserPermission(Permission):
"""Only signin user has this permission."""
def rule(self):
return UserRule()
有 4 种使用上述UserPermission
定义的方法:
1.用作视图装饰器
from .permissions import UserPermission
@app.route('/settings')
@UserPermission()
def settings():
"""User settings page, only accessable for sign-in user."""
return render_template('settings.html')
2.在视图代码中使用
from .permissions import UserPermission
@app.route('/settions')
def settings():
permission = UserPermission()
if not permission.check()
return permission.deny()
return render_template('settings.html')
3.在视图代码中使用(usingwith
语句)
from .permissions import UserPermission
@app.route('/settions')
def settings():
with UserPermission():
return render_template('settings.html')
4.在Jinja2模板中使用
首先,您需要将定义的权限注入模板上下文:
from . import permissions
@app.context_processor
def inject_vars():
return dict(
permissions=permissions
)
然后在模板中:
{% if permissions.UserPermission().check() %}
<a href="{{ url_for('new') }}">New</a>
{% endif %}