Flask-Admin 快速实现用户权限限制

这个办法基于以下两个事实:

  1. Flask Admin 本身是一个 Flask 蓝图
  2. Flask 的 ModelView 类可以通过 can_delete = True/False 等来关闭/开启相应的操作
    所以实现的办法是,给 Flask-Admin 蓝图的 before_request_funcs 注册一个 check_user_permission 函数,在每次请求之前根据用户的权限来刷新 ModelView 的设置。
    而蓝图的 before_request 必须要在 app.register_blueprint 调用之前,根据 Flask-Admin 创建蓝图和注册蓝图的流程来看,复写 ModelView 的 create_blueprint 这个函数就可以了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
class BaseModelView(ModelView):
def is_accessible(self):
return current_user.is_authenticated

def inaccessible_callback(self, name, **kwargs):
return abort(404)

def check_permission(self):
"""根据用户的权限来重新设置 create, edit, delete 以及 column_editable_list 的设置"""
self.can_create = True
self.can_edit = True
self.can_delete = True

if not self.column_editable_list_bk and self.column_editable_list:
self.column_editable_list_bk = self.column_editable_list[:]

if not current_user.has_create_access:
self.can_create = False
self.can_edit = False
self.can_delete = False
self.column_editable_list = list()
elif not current_user.has_edit_access:
self.can_edit = False
self.can_delete = False
self.column_editable_list = list()
elif not current_user.has_delete_access:
self.can_delete = False
self.column_editable_list = self.column_editable_list_bk

def create_blueprint(self, admin):
self.admin = admin
self.column_editable_list_bk = list()
...
# 以上部分都相同
if self.name is None:
self.name = self._prettify_class_name(self.__class__.__name__)
self.blueprint = Blueprint(self.endpoint, __name__,
url_prefix=self.url,
subdomain=self.admin.subdomain,
template_folder=op.join('templates', self.admin.template_mode),
static_folder=self.static_folder,
static_url_path=self.static_url_path)
# 主要是这一行
self.blueprint.before_request(self.check_permission)
# 以下都相同
...
return self.blueprint

这个实现办法还依赖于 Flask-Login 实现的用户登录机制,用户的权限验证在用户的 Model 中进行定义。