我有蓝图和一些网址功能,
admin_bp = Blueprint('admin', __name__)
@admin_bp.route('/dashboard', methods=['GET', ])
@flask_login.login_required
def dashboard():
context = {}
page = 'admin/dashboard.html'
return render_template(page, **context)
@admin_bp.route('/deny', methods=['GET', ])
@flask_login.login_required
def deny():
return 'hey bro you dont belong here'
我不想为此蓝图下的所有网址功能复制粘贴@flask_login.login_required
装饰器。有没有更好的方法可以为所有蓝图网址应用装饰器?
答案 0 :(得分:3)
您可以添加before_request()
作为将在视图中的每个请求之前运行的函数。
然后,您将需要添加装饰器以向before_request
函数注入附加功能。您将要导入login_required
装饰器,以确保每个端点都需要一个登录用户。该装饰器是flask_login
库的一部分。
由于您的视图似乎是管理员的一部分,因此我还建议您使用before_request
之类的东西向您的@role_required('admin')
函数添加自定义装饰器。该装饰器的功能将存在于其他地方并被导入。
@admin_bp.before_request
@login_required
def before_request():
""" Protect all of the admin endpoints. """
pass
答案 1 :(得分:0)
如何先检查用户:
from flask.ext.login import current_user
@admin_bp.before_request
def check_user():
if not current_user.is_authenticated():
abort(401)
# your other functions without `@flask_login.login_required`
答案 2 :(得分:0)
子类Blueprint
的子类,并覆盖route
方法。
import flask
class MyBlueprint(flask.Blueprint):
def route(self, rule, **options):
def decorator(f):
# these lines are copied from flask.Blueprint.route
endpoint = options.pop("endpoint", f.__name__)
self.add_url_rule(rule, endpoint, f, **options)
# At this point flask.Blueprint.route simply returns f.
# But you can nest a decorator.
def inner(*args, **kwargs):
# stuff you want to do before each request goes here
try:
result = f(*args, **kwargs)
# stuff you want to do on successful responses (probing status, headers, etc.) goes here
except Exception as e:
# stuff you want to do on error responses goes here
raise
return inner
现在在您的蓝图中使用新的子类:
-v1_blueprint = Blueprint('v1', __name__)
+v1_blueprint = MyBlueprint('v1', __name__)
无需更改单个路线。
这种方法的缺点是它从Flask内部复制代码。如果flask.Blueprint.route
的实现要在将来的版本中更改,则在升级Flask时,您需要将MyBlueprint与之同步。