LikeShop 后台菜单与权限体系解析:角色、权限、菜单表怎么配

一、前言

在之前的系列文章中,我写了 LikeShop 的源码结构、分层架构、二开规范和安全加固。这一篇聚焦后台管理系统最基础也最容易在二开时踩坑的部分------菜单与权限体系。

做过二开的人应该都有过这种经历:新增了一个管理后台的功能页面,代码写完了,接口也调通了,但登录后台一看,菜单里根本找不到入口。或者菜单有了,但运营账号点进去提示"无权限"。这些问题的根源,都是没有理解 LikeShop 权限体系的表设计和配置逻辑。

LikeShop 的权限控制体系基于经典的 RBAC 模型设计,通过用户-角色-权限的三层关联结构实现权限管理。核心逻辑是:先创建角色并分配权限,再创建管理员账号并绑定角色。不同角色拥有不同的菜单访问权限和操作权限。

这篇文章就把这套体系的表结构、配置流程和常见坑拆开讲清楚。

二、RBAC 权限模型的三层架构

LikeShop 的权限模型可以用一句话概括:管理员绑定角色,角色拥有菜单权限,菜单决定可见入口和可调用的接口。

三层结构的关系如下:

复制代码
ls_admin(管理员表)
    │ role_id(外键)
    ▼
角色(角色表)
    │ 权限关联
    ▼
菜单(菜单表)------ 决定可见菜单和可调用的接口权限

这个模型和很多后台系统的设计思路是一致的,但 LikeShop 在具体实现上有几个特点值得注意。

第一,菜单和权限节点是合并管理的。 在很多系统里,"菜单"和"权限节点"是两张独立的表------菜单管显示,权限节点管接口鉴权。但 LikeShop 把两者统一在菜单表中管理,一个菜单记录既决定了后台左侧导航栏是否显示这个入口,也决定了对应的接口是否有权限调用。这种设计的好处是配置更简单,不需要在两处分别维护;代价是权限粒度受菜单层级限制。

第二,权限校验在服务端强制执行。 前端隐藏菜单按钮只是"体验优化",不是安全措施。所有管理后台的接口必须通过权限校验中间件。官方在安全加固中明确:管理后台、商家权限做角色分级,接口增加路由权限校验,防止低权限账号越权操作高权限功能。

三、核心表结构解析

3.1 ls_admin 管理员表

ls_admin 是后台管理员的账号表,字段设计如下:

字段名 数据类型 注释
id int 主键
root tinyint 是否超级管理员:0-否;1-是
name varchar 名称
account varchar 账号
password varchar 密码
role_id int 角色id
multipoint_login tinyint 是否支持多处登录:1-是;0-否
disable tinyint 是否禁用:0-否;1-是
login_time int 最后登录时间
login_ip varchar 最后登录ip
sid int 商户id

几个关键字段的说明:

root 字段用于标识超级管理员。超级管理员不受角色权限限制,拥有所有菜单和接口的访问权限。二开时如果新增了权限节点,超级管理员默认就能访问,不需要额外配置。

role_id 是权限体系的核心关联字段,指向该管理员绑定的角色。一个管理员只能绑定一个角色------如果业务需要"一个人既是财务又是运营",需要新建一个同时包含财务和运营权限的角色,而不是给一个人绑定多个角色。

sid 是多商户版的商户标识。多商户版的 ls_admin 表同时存储了平台管理员和商户管理员的账号 ,通过 sid 字段区分:平台管理员的 sid 为 0,商户管理员的 sid 指向具体的商户。这意味着二开时查询管理员列表必须带上 sid 过滤条件,否则平台端会看到商户的管理员账号。

3.2 角色表

角色表存储角色的基本信息,关键字段包括:

字段名 注释
id 角色id
name 角色名称
desc 角色描述
auth_desc 角色权限

auth_desc 是角色的权限描述字段,记录该角色被分配了哪些菜单权限。角色列表接口返回的数据中,auth_desc 字段就是从这个字段读取的。

多商户版的角色表需要区分平台级角色和商户级角色。 平台级角色(如"平台运营")可以管理所有商户,商户级角色(如"店铺运营")只能管理自己店铺的数据。这个区分通过角色的 sid 字段实现------和 ls_admin 一样,sid = 0 表示平台级角色,sid 非 0 表示商户级角色。

3.3 菜单表

菜单表是权限体系中最核心的表,存储了所有后台菜单和权限节点的定义。关键字段包括:

字段名 注释
id 菜单id
pid 父级菜单id
name 菜单名称
path 路由路径
icon 图标
sort 排序
type 类型(目录/菜单/按钮)
perms 权限标识

pid 字段实现了菜单的树形结构。 pid = 0 表示顶级菜单,其他值指向父级菜单的 id。通过递归查询 pid,可以构建出完整的菜单树。

type 字段区分菜单类型。 通常有三种类型:目录(可展开的父级菜单)、菜单(具体的页面入口)、按钮(页面内的操作权限)。按钮类型的菜单不显示在左侧导航栏中,但会作为权限节点用于接口鉴权。

perms 字段是权限标识 ,通常用"模块:控制器:方法"的格式表示,比如 auth.admin:edit 对应编辑管理员接口。权限校验中间件会根据当前请求的路由,在菜单表中查找对应的 perms,然后检查当前用户的角色是否拥有这个菜单权限。

3.4 会话表 ls_admin_session

ls_admin_session 表管理管理员的登录会话:

字段名 注释
admin_id 用户id
terminal 客户端类型:1-pc管理后台;2-mobile手机管理后台
token 令牌
expire_time 到期时间
sid 商户id

管理员登录成功后,系统会生成一个 token 并写入这张表。后续请求的 token 校验就是通过查询这张表完成的。token 的过期时长配置在 server/config/project.php 的 admin_token 中,默认 8 小时。

四、菜单与权限的配置流程

理解了表结构之后,配置一个完整的权限体系需要按以下步骤操作。

4.1 第一步:添加菜单和权限节点

在管理后台的「权限管理」→「菜单」中,添加新的菜单或权限节点。这是整个配置流程的起点------没有菜单记录,后面的角色权限分配就无从谈起。

菜单权限的功能是设置后台菜单列表的新增、修改、删除,以及设置菜单权限。在配置时需要注意:

目录和菜单的区别。 目录(type=目录)是左侧导航栏中可展开的父级菜单,本身不对应页面;菜单(type=菜单)是具体的页面入口,点击后会打开对应的页面。

按钮权限的配置。 如果一个页面需要区分"可查看"和"可编辑"两种权限,需要为编辑操作单独添加一个按钮类型的权限节点。比如"管理员列表"页面,可以配置"查看管理员"和"编辑管理员"两个权限节点。

4.2 第二步:创建角色并分配权限

在「权限管理」→「角色」中创建角色。创建角色时需要填写角色名称和角色描述,然后勾选该角色可以访问的菜单权限。

官方的操作指引是:创建角色,不同角色不同权限。角色创建好之后再创建账号。

角色创建完成后,在角色列表中可以看到角色的名称、描述和权限信息。

4.3 第三步:创建管理员并绑定角色

在「权限管理」→「管理员」中创建管理员账号。创建时需要填写账号、名称、密码,并选择绑定的角色。

编辑管理员接口的参数中,role_id 是必填项,说明管理员必须绑定角色。同一个管理员也可以通过编辑接口重新分配角色。

4.4 第四步:验证权限

配置完成后,用新建的管理员账号登录后台,验证以下内容:

  • 左侧导航栏是否只显示了该角色被授权的菜单
  • 点击菜单后页面是否正常打开
  • 页面内的操作按钮是否根据权限显示或隐藏
  • 直接访问未授权的接口 URL 是否被拦截

五、二开时的常见坑与避坑指南

坑一:新增菜单后忘记分配权限

现象:新增了一个管理后台的菜单,超级管理员能看到,但普通运营账号登录后找不到这个菜单。

原因:菜单记录本身不携带权限信息,权限是通过角色分配的。新建的菜单需要手动勾选到对应角色的权限列表中。

解决:在「角色」编辑页面,重新勾选新增的菜单权限并保存。

坑二:按钮权限没有配置

现象:运营账号能看到"管理员列表"页面,但点击"编辑"按钮没有反应,或者提示"无权限"。

原因:只配置了"菜单"类型的权限节点,没有配置"按钮"类型的权限节点。页面能访问(菜单权限已授权),但编辑接口被拦截(按钮权限未授权)。

解决:在菜单管理中,为编辑操作添加一个按钮类型的权限节点,然后在角色中勾选这个权限节点。

坑三:多商户版查询管理员列表没有加 sid 过滤

现象:平台端的管理员列表中出现了商户的管理员账号,或者商户端看到了其他商户的管理员。

原因 :ls_admin 表同时存储平台管理员和商户管理员,通过 sid 字段区分。如果查询时没有加 sid 过滤条件,会把所有管理员都查出来。

解决 :平台端查询时加 sid = 0,商户端查询时加 sid = 当前商户id。

坑四:直接修改 ls_admin 的 role_id 绕过角色配置

现象 :为了方便,直接在数据库中把某个管理员的 role_id 改成另一个值,结果该管理员登录后权限异常。

原因 :角色切换不仅仅是改 role_id 字段,还需要清理该管理员的会话(ls_admin_session 中的 token)。如果不清理,管理员用旧 token 请求时,系统仍然按旧角色做权限判断。

解决 :修改管理员的角色后,让该管理员重新登录,或者手动清理 ls_admin_session 中该管理员的记录。

坑五:多商户版的权限节点注册到了错误的应用

现象:新增了一个商户端的管理接口,权限节点注册在了平台端的菜单中,导致商户账号无法访问。

原因:LikeShop 多商户版的管理后台分为平台端和商户端,两者的权限体系是独立的。平台端的菜单和商户端的菜单分别管理。

解决:明确新增的功能属于平台端还是商户端,将菜单权限节点注册到对应的应用模块中。

六、权限体系与接口鉴权的联动

理解菜单表如何与接口鉴权联动,是排查权限问题的关键。

6.1 鉴权流程

一次管理后台的接口请求,鉴权流程如下:

复制代码
请求到达 → AuthMiddleware 拦截
    ↓
① 从 Header 中提取 token
    ↓
② 查询 ls_admin_session 验证 token 有效性
    ↓
③ 根据 token 找到对应的 admin_id
    ↓
④ 查询 ls_admin 获取 role_id
    ↓
⑤ 根据 role_id 查询该角色拥有的菜单权限
    ↓
⑥ 根据当前请求的路由,匹配菜单表中的 perms 字段
    ↓
⑦ 匹配成功 → 放行;匹配失败 → 返回无权限

这条链路中的任何一环出问题,都会导致权限异常。

6.2 常见权限异常排查

现象 排查点
登录后菜单不显示 角色是否勾选了对应菜单权限
菜单显示但页面报错 接口是否有权限访问(检查按钮权限节点)
接口返回 403 当前路由是否在菜单表的 perms 中有对应记录
切换角色后权限没变 是否清理了旧的会话 token
超级管理员权限受限 ls_admin.root 字段是否为 1

七、总结

LikeShop 的后台权限体系基于 RBAC 模型,核心是三张表:

ls_admin 存储管理员账号,通过 role_id 绑定角色,通过 sid 区分平台和商户。

角色表 存储角色的权限分配信息,auth_desc 字段记录该角色拥有的菜单权限。

菜单表 存储所有菜单和权限节点,通过 pid 实现树形结构,通过 type 区分目录/菜单/按钮,通过 perms 字段与接口路由匹配。

配置流程是:添加菜单和权限节点 → 创建角色并分配权限 → 创建管理员并绑定角色 → 验证权限。

二开时最常见的坑是"新增菜单后忘记分配权限"和"按钮权限没有配置"。多商户版需要额外注意 sid 字段的过滤,避免平台端和商户端的数据泄露。

把这套体系的表结构和配置逻辑理解清楚,后台权限相关的问题就能快速定位和解决。

相关推荐
阿俊-全栈开发7 天前
LikeShop 二开环境搭建:本地开发、接口调试与前端联调全流程
likeshop
kepppt4 个月前
2026年开源商城系统推荐:哪种商城更适合长期二次开发?——真正决定商城系统长期价值的,从来不是“前期功能多少”,而是“后期还能不能持续扩展”
开源商城·likeshop
kepppt4 个月前
哪个开源商城系统更适合二次开发?2026年很多企业开始重视“长期维护成本”——很多系统前期开发很快,但真正决定企业未来成本的,其实是“后期还能不能继续改”
开源商城·likeshop