
做过业务系统的人应该都有这种体会权限模块在需求文档里通常写不了五行字但真正落地的时候却能折磨掉整个迭代周期。菜单要按角色区分按钮要按权限控制数据要按范围隔离PC端刚理清楚APP端又冒出来一堆系统级权限要处理。前几天我把 JNPF 的权限体系完整过了一遍PC 和 APP 两端一起接入不得不承认它的授权逻辑做得确实直观——配置完角色回头一看整个权限流转路径一目了然连产品经理都能看懂。这篇内容我打算顺着 JNPF 的权限设计思路把模型到落地完整拆开讲。包括用户-角色-权限这套经典模型怎么落地、菜单按钮权限怎么配、行级数据权限怎么设、PC 端和 APP 端如何保持一套配置两端生效最后再整理一些权限排查的实战经验。如果你正在做权限设计或者打算在低代码平台上落地权限管控这篇应该能帮你少踩几个坑。1. JNPF 权限体系整体拆解一套权限设计两端同时接管1.1 权限设计的第一步理清用户、角色、组织三层模型网上关于权限的资料一搜一大把但真正动手做的时候很多人第一步就歪了——上来就纠结某个按钮该放哪却忽略了最基础的模型。不管什么系统权限的本质都是同一件事判断某个主体能不能对某个资源执行某个操作。你肯定见过 Windows 弹窗提示你需要来自 Administrators 的权限才能删除也见过 Linux 下普通用户执行 sudo 命令时被告知不在 sudoers 文件中包括系统文件被 TrustedInstaller 锁定后、哪怕管理员也删不掉的经典场景。这些听起来像是系统问题底层逻辑和业务系统里的权限校验是完全一致的资源有归属、操作有范围、主体有等级系统只是按预设的规则做了一次身份核对。JNPF 把这种核对抽象成了三层模型用户、角色、组织。用户登录系统的自然人对应唯一的账号。组织天然的用户分组通常按公司部门、分支机构来建一个人只能属于一个主组织但可以兼职多个其他组织。角色权限的载体一头绑定用户另一头绑定功能权限和数据权限。很多刚接触权限设计的人会直接给用户分配权限用户少的时候问题不大一旦超过五十人、一百人维护成本就开始失控。张三离职要逐个清理权限李四调岗要重新配一堆入口王五一个账号兼顾多种职责的时候权限列表乱到根本没法审计。角色这层抽象的价值在于把人和权限彻底解耦——人怎么变不影响权限规则权限怎么调不影响账号结构。我给一个简单的对照表帮你快速理解这几层模型各自的角色实体解决的问题典型例子用户我是谁工号 10086 的小张组织我在哪个部门销售一部 / 华东大区角色我能做什么销售员、销售经理、财务审核功能权限我能看到哪些入口客户管理菜单、订单新增按钮数据权限我能看到哪些数据行仅本人客户 / 本部门订单这套模型不是 JNPF 发明的但它把模型的落地做到了配置化这是我认为最值得借鉴的地方。1.2 授权逻辑的直观呈现从角色到权限的流转路径配置权限最怕什么怕东一头西一头配完了自己都不知道用户最终能看到什么。JNPF 的权限管理页做得比较清楚角色是中心所有授权都从角色入口走。我以销售经理这个角色为例带着你走一遍完整的配置流程在角色管理里新建角色销售经理可以填备注说明适用范围。在角色成员 Tab 下把销售一组的小张、小李添加进去。切到功能权限 Tab按树形菜单勾选客户管理订单管理数据报表等菜单在按钮层面勾选新增编辑导出分配。切到数据权限 Tab数据范围选择本部门及以下部门保存。配置完成后使用小张的账号重新登录会看到菜单只渲染了勾选过的模块订单列表页自动只展示他所在部门的数据。这套流程走下来你基本就理解了权限的流转路径用户登录 → 携带用户ID → 权限框架加载角色集合 → 汇总功能权限编码和数据权限规则 → 前端动态渲染菜单和按钮 → 后端接口对每个操作做二次校验。权限数据在底层是下面这些表的协作结果理解数据来源之后排查问题会快很多表/关系作用用户表、组织表账号身份与归属角色表角色定义用户-角色关系人与角色的多对多绑定菜单表、按钮表功能资源的元数据定义角色-菜单按钮关系角色拥有的功能权限角色-数据规则关系角色限定的数据范围规则2. PC/APP 全场景覆盖同一套授权配置两套终端同步生效2.1 PC端菜单与按钮权限的配置要点先聊功能权限。功能权限分两层菜单权限和按钮权限。菜单权限控制的是这个页面你进不进得来按钮权限控制的是进到页面后这个操作你能不能点。很多前端朋友应该都搜过vue 按钮权限 怎么控制这类问题。在 JNPF 里按钮权限的配置其实很直接权限管理页把菜单和按钮按树形结构列在同一棵树上父级是菜单子级是按钮。给角色勾选菜单时子按钮默认不会一起勾上需要单独点选。勾选哪个按钮前端渲染的时候才会显示哪个按钮。这里补充一个很多团队都踩过的设计问题按钮权限到底该由前端隐藏还是后端拦截我的建议是前端控制显隐只是为了用户体验不构成安全防线。按钮隐藏得再彻底接口地址不一样能直接调用。真正的防线在后端。JNPF 的按钮权限在配置时其实对应着一组权限编码这些编码前端用来判断渲染后端接口的接口拦截同样会校验同一组编码。两端校验同一个东西权限才能真正闭环。我建议在初始化项目的时候就把按钮编码的命名规范定好比如统一用模块动作的格式customer:add、customer:delete、order:export。没有规范的话配置端和后端校验就很容易对不上权限配了却始终不生效。JNPF 的菜单和按钮管理里可以维护编码编码一旦固定就不要频繁改。2.2 移动端权限的适配细节与特殊处理APP 端的权限和 PC 端有一处明显差异除了业务权限还有一大块设备系统权限。定位权限、相机权限、相册权限、通知权限、麦克风权限这些在安卓和 iOS 上的申请机制各不相同有些版本对运行时权限的约束还在收紧比如安卓近几个版本对后台定位和录屏权限的限制就改过好几轮。如果你所在的项目正好踩了用户可以进入扫码页面但相机权限一直没弹窗的坑不用怀疑第一步先去看宿主 APP 的系统权限申请流程。JNPF 移动端的处理方式是双线并行业务权限继续复用服务端那一套配置设备系统权限则由移动端框架统一管理。页面在需要定位的时候调用统一 API 发起定位权限申请用户在系统弹窗里选择允许或拒绝如果之前选择了不再询问页面会引导用户到系统设置里手动打开。这两个权限体系一个管数据入口一个管设备能力最终在页面上共同决定功能是否可用。比如扫码打卡页面业务权限不够的话菜单都不渲染入口直接消失业务权限够了但相机权限没开页面能进但点扫码后提示去设置。这样拆开处理权限职责更清晰排查问题也更省力。2.3 一套配置多端同步的实现原理JNPF 的 PC 和 APP 共用同一个权限配置不用两端重复设置这个特性是它比较吸引人的地方。实现的原理并不玄乎权限数据统一存在服务端PC 端和 APP 端只是消费同一份数据。用户登录后客户端调用同一个权限接口拿到的菜单树和权限标识是一样的。区别只在前端渲染框架不同一个渲染成 PC 端桌面布局一个渲染成移动端列表布局。这里有个细节要注意JNPF 的菜单支持平台标识。同一个菜单可以同时勾选 PC、APP、小程序也可以指定只在一个端生效。比如某些报表后台操作只适合在 PC 端做把菜单的平台标识只勾选 PCAPP 端就不会展示。配置的时候如果发现 APP 端少了某个菜单第一反应应该是去菜单管理里查平台标识而不是反复重登账号、清缓存。移动端打开菜单背后的逻辑也值得一提APP 端登录后会拉取当前用户菜单树并生成本地路由打开一级页面时按需加载。这套机制和 PC 端保持一致所以无论你在哪个端改权限另一个端重新拉取权限数据后就会同步生效。3. 行级数据权限的设计与实现从入门到落地3.1 行级权限是什么从能不能看到这个功能到能看到哪些数据功能权限和数据权限是两个维度。功能权限回答的问题是你能不能用这个功能数据权限回答的问题是你用这个功能时能看到哪些数据。很多人理解权限的时候只关注了前者忽略了后者结果就出现了销售员能进客户列表页但能看到全公司所有客户的电话这种数据安全事件。行级权限也叫行级数据权限在 Java 后端领域是经典的实现难题——写 SQL 过滤条件、拼接权限范围、做缓存优化每一环都要设计。这也是行级权限 java这类搜索词长期有热度的原因。JNPF 把行级权限做成了可视化配置不需要写 SQL 就能实现常见的数据范围控制。在角色的数据权限配置里通常有以下几种数据范围选项数据范围含义适用场景仅本人只能看自己创建或负责的数据销售员的客户、普通员工的报销单本部门看本部门所有人的数据部门主管的管理视图本部门及以下部门看自己部门加所有下级部门的数据区域经理、大区负责人全部数据不限制范围管理员、财务、老板自定义规则按条件表达式筛选财务只看已审批单据等复杂场景我实际配置的时候最常用的是前四种自定义规则更多用在按状态过滤按金额区间过滤这类特殊需求上。以仅本人为例平台后端会解析成类似WHERE create_by #{当前用户ID}的条件追加到列表查询 SQL 上。整个过程配置完即可生效不需要写 Java 代码这就是低代码平台在这一块的核心优势。3.2 数据权限规则表达式实操复合条件怎么配简单场景用预设范围就行但业务总会冒出一些组合条件比如既能看本人创建的数据也能看所有已归档的数据。这种需求单靠一个范围选项搞不定需要用到自定义数据权限规则。JNPF 的自定义规则通常由三部分组成字段、操作符、值来源。值来源支持当前用户ID、当前用户部门ID、当前用户角色、固定值、自定义 SQL 片段。比如讨一个实际场景场景销售员能看到自己名下的客户以及所有状态为已归档的客户。配置思路把规则配置为两条用 OR 连接规则一customer.owner_id等于当前用户ID。规则二customer.status等于固定值已归档。平台在执行查询时会把第一条规则解析成owner_id 10086第二条解析成status archived两条规则做 OR 拼接后成为最终查询条件的一部分。这里有一个我在项目里真实踩过的坑自定义规则的条件优先级。规则多了以后OR 和 AND 的组合顺序会直接影响结果范围。默认情况下多规则之间是 OR 关系也就是放宽了限制。如果你的业务要求多个条件同时满足就得在规则配置里显式指定 AND 连接。最稳妥的做法是配完规则后先用测试账号跑一遍列表抽查几条边界数据确认没有越权也没有漏数据。尤其注意时间范围条件日期字段如果存的是带时分秒的时间戳而规则里用的格式不对很容易查不出数据。还有一个建议自定义规则尽量保持在三条以内。规则越长越难验证后期别人接手也看不懂。我见过一个客户把数据权限规则配了七八条员工离职之后根本没人敢动那个角色。权限配置也是需要管理的资产简洁本身就是一种可维护性。3.3 数据权限与功能权限的组合逻辑前端、接口、数据三层校验权限治理到位的系统通常会做三层校验顺序是前端控制显隐、后端接口校验、数据层行级过滤。拿销售员删除客户这个操作举例第一层前端按钮权限。角色没勾选删除按钮页面不渲染删除按钮普通用户从界面上根本没有删除入口。第二层后端接口校验。有人绕过前端直接调用删除接口服务端会校验当前用户是否拥有customer:delete这个权限编码没有就返回 403。第三层数据权限校验。假设用户拥有删除权限但只能删自己名下的客户后端处理删除的时候还会做一次行级校验确保被删除的数据确实在用户的数据范围内。JNPF 平台内置的 CRUD 接口会自动执行这三层校验这也是为什么列表页、表单页这类标准功能基本不用写额外权限代码。但如果你在业务里自定义了 API那么后两层校验就得自己在接口里接上平台的权限框架或者调用平台提供的权限校验方法。这一段很多小伙伴会忽略测试阶段发现接口洞的时候才恍然大悟原来按钮隐藏不等于安全。4. 授权逻辑背后的常见问题与排查手册4.1 刚改了权限不生效问题可能出在哪几个环节这个问题几乎每次权限培训都会被问到。改了角色权限重新登录界面还是老样子最常见的几个原因如下按优先级从高到低排查缓存。浏览器缓存、APP 本地缓存、服务端 Redis 缓存只要有一层缓存没刷新新权限就不会立刻生效。JNPF 登录时会重新拉取权限快照所以改完权限后让对应用户退出重登是第一步。多角色叠加。用户可能有多个角色A 角色没有某个菜单但 B 角色有最终权限取的是并集。用户看到菜单不代表 A 角色配置成功可能只是 B 角色的权限在起作用。要确认配置是否生效最好用一个只挂单一角色的测试账号去验证。菜单平台标识。PC 端能看到APP 端看不到优先检查菜单的平台标识是否勾选了 APP。这项最常见也最容易忽略。权限编码不匹配。按钮权限编码和接口校验编码不一致就会出现前端该显示的显示了、后端却拒绝访问或者前端隐藏了、后端却能直连的诡异现象。借用前面提过的 Windows 权限问题来类比你需要来自 Administrators 的权限才能删除但切换了管理员账号还是删不掉的时候是不是会先怀疑文件被 TrustedInstaller 锁定、而不是反复换账号重试业务系统的权限排查也是同一个思路先看清当前账号实际属于哪个角色、目标资源的权限由谁的规则控制再去验证修改为什么没有生效。盲目重登十次不如花三十秒把权限链路过一遍。4.2 按钮权限与接口校验的联动问题前端隐藏了按钮调接口却依然能拿到数据这个问题被问过很多次。先说结论按钮权限的前端隐藏只负责用户体验接口校验负责真正的安全。两者如果不能对齐权限体系就是破的。JNPF 在平台内置功能上对齐做得比较好因为权限标识在配置端和后端框架里是同一套。问题大多出在扩展开发上。你在代码生成器里加了一个自定义按钮也在页面上配置了按钮编码但如果忘了在后端接口里加上同样的权限校验那这个按钮就只是看上去有权限控制。很多团队处理这个问题的方式是每次发布权限相关需求QA 必须做一次接口直调测试。也就是绕过前端页面用工具直接调用带权限的 API验证无权限用户是否会被拒绝。这个方法成本低、效果明显强烈建议纳入权限测试用例。4.3 权限不够用的时候如何优雅扩展平台默认的权限模型覆盖了大多数业务场景但总会有一些个性化需求比如外部系统用户同步HR 系统里维护组织架构需要定时同步到 JNPF。动态授权某些用户登录后要根据外部业务状态临时追加角色。自定义数据源数据权限的自定义规则需要支持跨库查询。面对这些场景优先考虑在平台外层做集成而不是直接改平台核心权限模块的源码。JNPF 提供了用户、角色、组织相关的接口可以在外部系统里做同步脚本登录后也支持通过事件或扩展逻辑对临时权限做调整。改源码一时爽后期版本升级的时候会非常痛苦这是我长期做平台类项目攒下的教训。还有一点经验之谈权限配置最好在项目初期就定好规则。见过不少项目上线后才发现权限模型撑不住这时候再调整角色设计迁移成本远比想象的高。先把用户类型梳理清楚把职责权限画成矩阵再往平台上落整个过程会顺畅很多。我个人在权限配置上踩得比较深的一个坑是把它当成纯前端的事来做了。后来被测试在接口层找到漏洞才真正养成前端控制显隐、后端控制接口、数据层再兜底三层校验的习惯。JNPF 把这套逻辑做成可视化之后最大的价值不是省了写代码的时间而是让整个团队的沟通成本降下来了——产品经理能看懂权限规则测试能说清楚权限预期后端不用再靠口述解释数据范围。如果你们团队也正在权衡权限方案不妨先按角色把功能权限和数据权限分开梳理再对照本文的配置路径过一遍很多看似复杂的东西其实只是缺少一个直观的载体。