按钮级权限控制需后端接口每次请求校验、权限码精确到操作粒度(如article:delete)、前端仅做显隐优化;权限码须路由绑定、数据库唯一存储、redis缓存角色权限集并及时失效;前端初始化获取权限列表并本地校验,数据库须独立建模四张表支持动态管理。

按钮级权限控制不是前端藏一藏就完事,关键在后端接口每请求都校验、权限码精确到操作粒度、前端只做显隐优化。核心是“后端守门、前端配合”。
权限码必须定义到具体操作级别
不能用控制器方法名(如delete)直接当权限码,它缺少模块上下文;也不能硬编码在代码里(如'admin/article/delete'),改路由就得改逻辑。
- 推荐方式:在路由定义时显式绑定权限码,例如:
Route::post('admin/article/delete', 'ArticleController@delete')->option('permission', 'article:delete'); - 数据库中
sys_permission.name字段必须存这个字符串(如article:delete),加唯一索引,避免拼写错误 - 命名统一用英文冒号分隔,不用空格、中文或特殊符号,方便程序匹配
后端接口必须每次请求都鉴权
别信“登录时查一次权限缓存就够了”——权限可能随时被运营调整,缓存不及时就会越权或误拒。
- 在中间件(如
PermissionCheck)中统一提取路由绑定的permission选项,调用checkPermission($code) - 校验逻辑走 Redis 缓存:
key = 'role_permissions_' . $roleId,值为该角色所有权限码的集合(Set结构),用SISMEMBER判断,O(1) 时间复杂度 - 权限变更(如分配新角色、修改角色权限)时,必须同步清理对应
role_permissions_*缓存,否则新权限永不生效 - 禁用 static 变量缓存——Swoole 下 worker 不共享,极易误判
Vue 前端只负责体验,不替代安全
按钮显示与否只是视觉反馈,不能作为权限依据。关键操作前仍需本地检查权限码是否存在。
- 按钮加上提示属性:
<button data-permission="article:delete">删除</button> - 页面初始化时,调用
/api/auth/permissions接口一次性获取当前用户全部权限码数组(已从 Redis 缓存读取) - 遍历 DOM,隐藏
data-permission值不在权限列表中的按钮 - 点击按钮触发关键操作(如提交表单、调用删除接口)前,先检查
article:delete是否在本地权限数组中;缺失则直接报错,不发请求
数据库与表结构要支持动态权限管理
权限不能存在用户表 JSON 字段里,必须独立建模,才能走索引、可审计、支持实时生效。
- 建议四张表:
sys_user(用户)、sys_role(角色)、sys_permission(权限)、sys_role_permission(角色-权限关联) -
sys_permission表必须含name(如article:delete)、type(menu/api/button)、status(0禁用,1启用) - 不要滥用
condition字段——每次校验都拼SQL,易引发全表扫描;真需要动态条件(如“仅编辑自己创建的内容”)再启用
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











