当前位置: 首页 > news >正文

若依框架中权限字符(perms)的作用

让我用一个更简单的例子来解释权限字符(perms)的作用:

场景举例:导出功能

假设系统中有3个页面都需要导出功能:

  1. 用户管理页面
  1. 订单管理页面
  1. 商品管理页面
方案1:不使用perms(传统方式)
  1. 在菜单表中需要创建3个按钮记录:

    sql

    Apply to SysMenu.java

    -- 用户管理的导出按钮

    INSERT INTO sys_menu (menu_id, menu_name, menu_type, parent_id) 

    VALUES (101, '导出用户', 'F', 100);

    -- 订单管理的导出按钮

    INSERT INTO sys_menu (menu_id, menu_name, menu_type, parent_id) 

    VALUES (201, '导出订单', 'F', 200);

    -- 商品管理的导出按钮

    INSERT INTO sys_menu (menu_id, menu_name, menu_type, parent_id) 

    VALUES (301, '导出商品', 'F', 300);

  1. 如果管理员需要导出权限,需要在角色-菜单关联表中插入3条记录:

    sql

    Apply to SysMenu.java

    INSERT INTO sys_role_menu (role_id, menu_id) VALUES (1, 101); -- 用户导出

    INSERT INTO sys_role_menu (role_id, menu_id) VALUES (1, 201); -- 订单导出

    INSERT INTO sys_role_menu (role_id, menu_id) VALUES (1, 301); -- 商品导出

方案2:使用perms(若依方式)
  1. 在菜单表中创建按钮时,使用相同的权限字符:

    sql

    Apply to SysMenu.java

    -- 用户管理的导出按钮

    INSERT INTO sys_menu (menu_id, menu_name, menu_type, parent_id, perms) 

    VALUES (101, '导出用户', 'F', 100, 'system:export');

    -- 订单管理的导出按钮

    INSERT INTO sys_menu (menu_id, menu_name, menu_type, parent_id, perms) 

    VALUES (201, '导出订单', 'F', 200, 'system:export');

    -- 商品管理的导出按钮

    INSERT INTO sys_menu (menu_id, menu_name, menu_type, parent_id, perms) 

    VALUES (301, '导出商品', 'F', 300, 'system:export');

  1. 管理员只需要被授予一次导出权限:

    sql

    Apply to SysMenu.java

    INSERT INTO sys_role_permission (role_id, permission) 

    VALUES (1, 'system:export');

主要区别

  1. 权限管理更简单
  • 不使用perms:每新增一个导出功能,都需要给角色重新授权
  • 使用perms:只要角色有system:export权限,就能使用所有导出功能
  1. 代码实现更统一
  • 不使用perms:每个导出接口都需要单独写权限校验
  • 使用perms:所有导出接口可以用同一个权限注解@PreAuthorize("@ss.hasPermi('system:export')")
  1. 维护成本更低
  • 不使用perms:新增导出功能时,需要修改菜单表和角色授权
  • 使用perms:新增导出功能时,只需添加菜单记录,无需修改角色授权

实际应用示例

java

Apply to SysMenu.java

// 用户导出接口

@PreAuthorize("@ss.hasPermi('system:export')")

public void exportUsers() {

    // 导出用户逻辑

}

// 订单导出接口

@PreAuthorize("@ss.hasPermi('system:export')")

public void exportOrders() {

    // 导出订单逻辑

}

// 商品导出接口

@PreAuthorize("@ss.hasPermi('system:export')")

public void exportProducts() {

    // 导出商品逻辑

}

这样,只要用户有system:export权限,就能使用所有导出功能,不需要为每个导出功能单独授权。这就是权限复用的核心思想。

所以只是这么用吗这个权限字符?为什么要所有导出都能导出,如果我只允许订单导出怎么办?

啊,这是个很好的问题!让我重新解释一下权限字符(perms)的更完整用法:

1. 权限字符的层级设计

权限字符通常采用"模块:操作"的格式,可以设计多个层级:

java

Apply to SysMenu.java

// 基础权限

system:export          // 所有导出权限

order:export          // 订单导出权限

user:export           // 用户导出权限

// 更细粒度的权限

order:export:detail   // 订单详情导出

order:export:summary  // 订单汇总导出

2. 实际应用场景

场景1:只允许订单导出

java

Apply to SysMenu.java

// 订单导出接口

@PreAuthorize("@ss.hasPermi('order:export')")

public void exportOrders() {

    // 导出订单逻辑

}

// 用户导出接口

@PreAuthorize("@ss.hasPermi('user:export')")

public void exportUsers() {

    // 导出用户逻辑

}

数据库配置:

sql

Apply to SysMenu.java

-- 订单导出按钮

INSERT INTO sys_menu (menu_id, menu_name, menu_type, parent_id, perms) 

VALUES (201, '导出订单', 'F', 200, 'order:export');

-- 用户导出按钮

INSERT INTO sys_menu (menu_id, menu_name, menu_type, parent_id, perms) 

VALUES (101, '导出用户', 'F', 100, 'user:export');

-- 角色权限配置

INSERT INTO sys_role_permission (role_id, permission) 

VALUES (1, 'order:export');  -- 只给订单导出权限

场景2:不同级别的导出权限

java

Apply to SysMenu.java

// 订单详情导出

@PreAuthorize("@ss.hasPermi('order:export:detail')")

public void exportOrderDetail() {

    // 导出订单详情

}

// 订单汇总导出

@PreAuthorize("@ss.hasPermi('order:export:summary')")

public void exportOrderSummary() {

    // 导出订单汇总

}

3. 权限字符的优势

  1. 灵活的权限控制
  • 可以精确控制到具体功能
  • 可以设置不同级别的权限
  1. 权限组合

    java

    Apply to SysMenu.java

    // 需要同时具备多个权限

    @PreAuthorize("@ss.hasPermi('order:export') and @ss.hasPermi('order:view')")

    public void exportOrders() {

        // 导出订单逻辑

    }

  1. 权限继承

    java

    Apply to SysMenu.java

    // 检查是否有订单模块的任何权限

    @PreAuthorize("@ss.hasPermi('order:*')")

    public void orderOperation() {

        // 订单相关操作

    }

4. 实际使用建议

  1. 权限命名规范

    text

    Apply to SysMenu.java

    模块:操作:子操作

    例如:

    order:export:detail    // 订单详情导出

    order:export:summary   // 订单汇总导出

    user:add              // 用户添加

    user:edit             // 用户编辑

  1. 权限粒度控制

    java

    Apply to SysMenu.java

    // 粗粒度权限

    @PreAuthorize("@ss.hasPermi('order:*')")

    // 细粒度权限

    @PreAuthorize("@ss.hasPermi('order:export:detail')")

  1. 权限组合使用

    java

    Apply to SysMenu.java

    // 需要同时具备多个权限

    @PreAuthorize("@ss.hasPermi('order:export') and @ss.hasPermi('order:view')")

    // 具备任一权限即可

    @PreAuthorize("@ss.hasPermi('order:export') or @ss.hasPermi('order:view')")

所以,权限字符(perms)不仅可以实现权限复用,更重要的是可以实现精确的权限控制。你可以根据业务需求,设计不同粒度的权限控制,而不是简单地让所有导出功能共享同一个权限。

所以,它这个权限字符设计在菜单表更合理是吧,能设计在角色表中吗?就是这个perms

是的,权限字符(perms)设计在菜单表中更合理,原因如下:

1. 菜单表设计更合理的原因

  1. 与菜单按钮一一对应

    sql

    Apply to SysMenu.java

    -- 菜单表

    CREATE TABLE sys_menu (

        menu_id BIGINT PRIMARY KEY,

        menu_name VARCHAR(50),

        menu_type CHAR(1),    -- M目录 C菜单 F按钮

        perms VARCHAR(100)    -- 权限字符

    );

    -- 示例数据

    INSERT INTO sys_menu VALUES 

    (101, '导出用户', 'F', 'user:export'),

    (102, '编辑用户', 'F', 'user:edit'),

    (201, '导出订单', 'F', 'order:export');

  1. 权限与UI元素绑定
  • 每个按钮/菜单项都有对应的权限字符
  • 前端可以根据权限字符控制按钮的显示/隐藏
  • 后端可以根据权限字符控制接口的访问
  1. 维护更方便
  • 添加新功能时,直接在菜单表中配置权限
  • 权限与功能点一一对应,便于管理

2. 为什么不适合放在角色表中

  1. 数据冗余

    sql

    Apply to SysMenu.java

    -- 角色表(不推荐)

    CREATE TABLE sys_role (

        role_id BIGINT PRIMARY KEY,

        role_name VARCHAR(50),

        perms VARCHAR(1000)  -- 存储所有权限字符,会导致数据冗余

    );

  1. 维护困难
  • 需要手动维护权限字符串
  • 容易出错
  • 难以追踪权限来源
  1. 扩展性差
  • 新增权限需要修改角色表
  • 难以实现细粒度的权限控制

3. 正确的设计方式

sql

Apply to SysMenu.java

-- 1. 菜单表(包含权限字符)

CREATE TABLE sys_menu (

    menu_id BIGINT PRIMARY KEY,

    menu_name VARCHAR(50),

    menu_type CHAR(1),

    perms VARCHAR(100)

);

-- 2. 角色表

CREATE TABLE sys_role (

    role_id BIGINT PRIMARY KEY,

    role_name VARCHAR(50)

);

-- 3. 角色-菜单关联表

CREATE TABLE sys_role_menu (

    role_id BIGINT,

    menu_id BIGINT

);

4. 实际使用示例

java

Apply to SysMenu.java

// 1. 菜单配置

INSERT INTO sys_menu VALUES 

(101, '导出用户', 'F', 'user:export'),

(102, '编辑用户', 'F', 'user:edit');

// 2. 角色配置

INSERT INTO sys_role VALUES 

(1, '管理员'),

(2, '普通用户');

// 3. 角色-菜单关联

INSERT INTO sys_role_menu VALUES 

(1, 101),  -- 管理员可以导出用户

(1, 102),  -- 管理员可以编辑用户

(2, 101);  -- 普通用户只能导出用户

5. 权限控制实现

java

Apply to SysMenu.java

// 1. 前端控制

<button v-if="hasPermi('user:export')">导出用户</button>

<button v-if="hasPermi('user:edit')">编辑用户</button>

// 2. 后端控制

@PreAuthorize("@ss.hasPermi('user:export')")

public void exportUsers() {

    // 导出用户逻辑

}

@PreAuthorize("@ss.hasPermi('user:edit')")

public void editUser() {

    // 编辑用户逻辑

}

6. 优势总结

  1. 结构清晰
  • 权限与功能点一一对应
  • 便于管理和维护
  1. 扩展性好
  • 易于添加新权限
  • 支持细粒度控制
  1. 使用方便
  • 前端可以直接根据权限控制显示
  • 后端可以直接使用注解控制访问
  1. 维护简单
  • 权限变更只需修改菜单表
  • 角色权限通过关联表管理

所以,权限字符(perms)设计在菜单表中是最合理的选择,它能够更好地支持权限管理系统的实现和维护。

http://www.xdnf.cn/news/993241.html

相关文章:

  • Spark on yarn的作业提交流程
  • Android7 Input(十一)App View InputEvent事件分发
  • Appium + Python 测试全流程
  • STM32外设学习之串口
  • ABP vNext + Redis Streams:构建实时事件驱动架构
  • Redis的常用配置详解
  • 如何彻底解决缓存击穿、缓存穿透、缓存雪崩
  • Redis集群模式之Redis Cluster(1)
  • SPP——神经网络中全连接层输出尺寸限制的原因和解决办法
  • 【强连通分量 拓扑序】P9431 [NAPC-#1] Stage3 - Jump Refreshers|普及+
  • HashMap真面目
  • Python数据可视化艺术:动态壁纸生成器
  • 《C++初阶之类和对象》【类 + 类域 + 访问限定符 + 对象的大小 + this指针】
  • Vue3+TypeScript实现中介者模式
  • 【Docker管理工具】安装容器管理工具Oxker
  • 通信网络编程2.0——JAVA
  • HALCON第五讲-> 形状匹配
  • 每日八股文6.12
  • 蓝桥杯20112 不同的总分值
  • 网页怎么调用字体ttf文件?
  • Go 语言安装指南:并解决 `url.JoinPath` 及 `Exec format error` 问题
  • [论文阅读] 系统架构 | 零售 IT 中的微服务与实时处理:开源工具链与部署策略综述
  • MySQL数据库:关系型数据库的基石
  • AVL树的平衡艺术:用C++写出会“站立”的二叉树(未完待续)
  • 【SAS求解多元回归方程】REG多元回归分析-多元一次回归
  • windows基线配置
  • ss928v100模型的导出、量化和转换
  • 中科院1区|IF6.7:基于PCA/OPLS-DA和KEGG通路分析的多组学整合,揭示沙棘-水飞蓟复方改善高脂血症的分子基础
  • C语言:指针进阶(下)
  • OpenAI推出专业级大模型o3-pro:为高精度任务而生