Skip to content

权限节点配置

后端代码中的 permission_required = ("sys:example:page",) 定义了接口所需的权限字符串,但权限节点本身需要在数据库中配置,才能在「菜单管理」中分配给角色。

权限字符串格式

sys:{module}:{action}
部分说明示例
sys系统前缀(固定)sys
module模块名(小写)example
action操作名page / add / update / delete

Example 模块的权限节点

权限字符串说明HTTP 方法路径
sys:example:page分页查询GET/example/page
sys:example:detail详情查询GET/example/detail/{id}
sys:example:list列表查询GET/example/list
sys:example:add新增案例POST/example/add
sys:example:update更新案例PUT/example/update
sys:example:delete删除案例DELETE/example/delete/{id}
sys:example:status状态变更PUT/example/status

权限校验流程

用户请求 → check_login(JWT 校验) → PermissionRequired(权限校验)
  ├── 用户 ID = 1(admin)→ 跳过权限校验,直接放行
  └── 其他用户 → 查询角色权限列表 → 匹配权限字符串 → 放行 / 拒绝

PermissionRequired 源码

python
class PermissionRequired(PermissionRequiredMixin):
    def has_permission(self):
        permissions = self.get_permission_required()
        user_id = get_user_id(self.request)

        # 超级管理员自动放行
        if user_id and user_id != 1:
            from application.menu import services
            permission_list = services.get_user_permissions(user_id)
            for permission in permissions:
                if permission not in permission_list:
                    return False
        return True

    def handle_no_permission(self):
        return R.failed("暂无操作权限", 401)

关键点

  • 用户 ID 为 1 是超级管理员:自动跳过所有权限校验
  • 权限校验失败返回 401:前端收到 401 后提示"暂无操作权限"
  • 权限节点从菜单表查询get_user_permissions(user_id) 返回用户拥有的所有权限节点

配置步骤

第一步:添加菜单节点

登录管理后台,进入「系统管理 -> 菜单管理」:

  1. 找到或创建「案例管理」菜单项
  2. 在该菜单下添加「权限」类型子节点
  3. 填写以下信息:
字段
菜单类型权限
权限标识sys:example:page
菜单名称案例查询

第二步:批量添加权限节点

为每个接口重复上述步骤,添加全部权限节点。

查询类权限(page、detail、list)通常合并为一个节点 sys:example:list,减少配置工作量。写操作(add、update、delete、status)建议独立配置,便于细粒度控制。

第三步:分配给角色

权限节点创建并启用后,需将其分配给角色,用户才能通过角色继承相应权限。

操作路径:「系统管理 -> 角色管理」

  1. 在角色列表中找到目标角色,点击「编辑」进入权限配置页面
  2. 在权限树中展开「案例管理」模块,勾选需要分配的权限节点
  3. 点击「保存」提交配置,权限即生效

注意:权限分配后,拥有该角色的用户需重新登录或刷新页面才能获取最新权限。

前端权限控制

前端使用 v-perm 指令控制按钮显示:

vue
<!-- 新增按钮 -->
<el-button v-perm="['sys:example:add']">添加案例</el-button>

<!-- 批量删除按钮 -->
<el-button v-perm="['sys:example:batchDelete']">批量删除</el-button>

操作栏按钮使用 auth 属性:

javascript
{
  label: '编辑',
  icon: 'Edit',
  onClick: handleEdit.bind(null, record),
  auth: ['sys:example:update'],
}

SQL 直接插入权限节点

如果需要通过 SQL 直接插入权限节点(如初始化脚本),参考以下语句:

sql
-- 假设案例管理菜单 ID 为 200
INSERT INTO django_menu (name, parent_id, path, component, perms, type, icon, sort, create_time, is_delete)
VALUES
('案例查询', 200, NULL, NULL, 'sys:example:page', '1', NULL, 0, NOW(), 0),
('案例新增', 200, NULL, NULL, 'sys:example:add', '1', NULL, 0, NOW(), 0),
('案例编辑', 200, NULL, NULL, 'sys:example:update', '1', NULL, 0, NOW(), 0),
('案例删除', 200, NULL, NULL, 'sys:example:delete', '1', NULL, 0, NOW(), 0),
('案例状态', 200, NULL, NULL, 'sys:example:status', '1', NULL, 0, NOW(), 0);

其中 type='1' 表示权限类型节点(非菜单)。

开发要点

  1. 权限字符串必须与代码中的 permission_required 完全一致
  2. admin 用户(ID=1)自动跳过权限校验:开发阶段可用 admin 测试
  3. 权限节点是菜单的子节点:type 为 1(权限),不是 0(菜单)
  4. 查询权限可适当合并:减少配置复杂度
  5. 写操作权限建议独立:便于细粒度控制

总结

权限节点是菜单的子节点(type=1),命名规范为 sys:{模块}:{操作}。后端通过 PermissionRequired 混入类校验,前端通过 v-perm 指令控制按钮显示。admin 用户(ID=1)自动跳过权限校验,查询权限可适当合并,写操作权限建议独立以实现细粒度控制。

小蚂蚁云团队 · 提供技术支持