原创

权限系统怎么做

paste-image-1782437476539.png

很多人第一次做权限系统,会先想角色:管理员、普通用户、会员、访客、超级管理员。角色越列越多,代码里到处写判断,最后自己也分不清谁能做什么。

权限系统的核心不是角色名,而是控制“谁能对什么资源做什么动作”。只要这句话想清楚,权限设计就会简单很多:谁是主体,资源是什么,动作有哪些,边界在哪里。

早期产品不需要一上来做复杂 RBAC、ABAC、多租户策略和权限配置后台。但必须从一开始避免把权限写死在页面里。否则产品一旦接入付费、团队、管理员、API,就会很难改。

先分清认证和授权

做权限前,先分清两个概念:认证和授权。

认证解决“你是谁”。比如用户通过邮箱、密码、验证码、Google 登录证明自己是某个账号。授权解决“你能做什么”。比如你能不能查看这个项目、导出这个报告、邀请成员、修改账单。

很多权限问题,是把认证当授权。用户登录了,不代表他能访问所有资源;用户是付费用户,也不代表他能管理团队账单;用户能看到列表,也不代表他能删除数据。

所以系统里要有明确边界:登录状态只代表身份成立,具体操作必须继续检查权限。前端可以根据权限隐藏按钮,但真正的权限判断必须在后端做。

用“资源 + 动作”定义权限

权限最清楚的表达方式,是资源加动作。

资源是系统里被访问或管理的对象,比如项目、报告、文件、团队、订单、API Key、配置项。动作是用户对资源做的事情,比如查看、创建、编辑、删除、导出、分享、邀请、支付、取消订阅。

不要一开始就写很多抽象权限名。先列出你的资源,再列出每个资源允许的动作。比如:

report:view
report:create
report:export
project:update
team:invite
billing:manage
admin:user_view

这种命名虽然朴素,但非常清楚。以后无论你用角色、套餐还是团队身份,都可以映射到这些权限上。

权限命名越贴近资源和动作,系统越不容易失控。

角色只是权限集合

角色不是权限系统的本体,而是权限的集合。比如“管理员”这个角色,可能包含用户管理、订单查看、任务重试、配置修改等权限;“普通成员”可能只能查看和创建项目;“访客”可能只能查看共享结果。

早期产品可以先定义少量角色:Owner、Admin、Member、Viewer。不要一开始就设计十几个角色。角色越多,测试成本越高,用户也越难理解。

每个角色都应该能用一句话解释:这个角色负责什么,不能做什么。比如 Owner 可以管理账单和成员,Admin 可以管理项目和内容但不能修改账单,Member 可以创建和编辑自己的内容,Viewer 只能查看。

如果一个角色解释不清,它很可能只是你为了处理某个特殊情况临时加的补丁。

权限必须绑定资源归属

很多权限漏洞不是因为角色错了,而是因为没有检查资源归属。

比如用户 A 登录后访问 /reports/123,系统不能只检查他是否登录,还要检查报告 123 是否属于用户 A,或者是否属于 A 所在团队,或者是否被共享给 A。否则用户改一个 ID 就可能看到别人的数据。

这类问题叫越权访问,是早期产品很容易忽视的安全风险。尤其是报告、文件、订单、发票、API Key、私有项目,一定要做资源归属检查。

权限判断应该发生在数据查询和业务操作层,而不是只靠页面路由。用户看不到按钮,不代表他不能构造请求。真正安全的系统,是后端每次关键操作都校验资源归属和动作权限。

免费版和付费版也属于权限

很多人把套餐限制写成业务判断,而不是权限判断。比如免费用户不能导出、每天只能生成 5 次、不能使用高级模型、不能保存历史记录。这些其实都是权限或额度的一部分。

如果从一开始把套餐能力纳入权限系统,后面定价和升级会更容易。比如:

export:basic
export:watermark_free
model:advanced
history:save
quota:monthly_100

当然,额度类权限不一定都适合写成固定权限。有些更适合单独做 usage 和 limit 表。但思路一致:用户能不能做某个动作,取决于身份、套餐、资源归属和当前用量。

不要把付费判断散落在前端组件里。否则以后改套餐,会变成一次全站找判断的痛苦工作。

后台权限要更克制

后台权限比前台更敏感。因为后台可以查看用户、修改状态、处理订单、重试任务、调整配置。一旦误操作或越权,影响会很大。

早期后台可以先做简单分级:普通管理员、只读管理员、超级管理员。普通管理员可以处理用户和任务,只读管理员只能查看,超级管理员才能修改配置和敏感数据。

所有高风险后台操作都应该有操作记录。比如修改用户额度、取消订单状态、重试任务、切换配置、封禁用户。记录内容至少包括操作人、操作时间、操作对象、修改前后状态。

后台权限不一定一开始做得很复杂,但必须可追溯。

一个最小权限模型

早期 SaaS 可以用下面这个模型:

User:用户身份
Team:团队或工作空间,可选
Resource:项目、报告、文件、订单等
Role:Owner / Admin / Member / Viewer
Permission:resource:action
Plan:Free / Pro / Team
Usage:当前用量
Policy:身份 + 角色 + 套餐 + 资源归属 + 用量 => 是否允许

第一版甚至可以没有 Team。个人产品只需要 User、Resource、Plan、Usage、Permission。等团队协作出现真实需求时,再引入 Team 和成员角色。

关键是不要把权限逻辑写得散乱。最好集中在一个权限判断函数或策略层里,让所有关键操作都走同一套判断。

总结

权限系统不是角色名列表,而是主体、资源、动作和边界的组合。先分清认证和授权,再用资源加动作定义权限,把角色当成权限集合,同时检查资源归属、套餐权益和用量限制。

早期产品的权限系统应该简单,但不能随意。前端可以隐藏入口,后端必须真正校验。只要从第一版就把权限判断集中起来,后面接团队、付费、后台和 API 都会轻松很多。

作业

  • 列出你的产品中最重要的 5 类资源。
  • 为每类资源写出用户可能执行的动作。
  • 设计不超过 4 个角色,并写清每个角色不能做什么。
  • 检查所有详情页和 API 是否校验资源归属。
  • 把套餐限制整理成权限或额度规则。

下一节课

数据库第一次怎么建:数据库不是先把所有字段想完,而是先围绕核心对象和核心流程建立可演进的数据结构。

正文到此结束
Loading...