账号、权限与数据模型
先定义身份、资源归属和关键状态,再实现登录与后台页面。
很多产品先做登录页,最后才发现真正困难的是:谁能看什么、谁能改什么、付款后拥有什么。
登录只是确认身份。权限和数据归属才决定系统是否安全、业务是否能正常恢复。
这一章的产出是一张表和一组状态定义,不是一个登录页面。
表画对了,登录页半天就能做完。表没画,登录页做得再快也要重做。
先列出角色
第一版通常只需要少量角色:
- 访客:只能访问公开内容和开始注册
- 普通用户:管理自己的任务、文件和订单
- 付费用户:在普通权限上增加明确权益
- 运营人员:处理订单、退款、支持和异常
- 管理员:执行少量高风险配置操作
最常见的漏洞是把"已登录"当成万能权限。
登录只回答了"你是谁",没有回答"这个东西是不是你的"。每个接口都要单独检查资源归属——只要接口里带了一个 ID 参数,就要检查这个 ID 指向的东西属不属于当前用户。
改一下地址栏里的 ID 就能看到别人数据,是真实产品里最高频的一类事故。
运营人员和管理员早期可以是同一个人,但权限要分开定义。以后请人帮忙处理支持时,你不希望顺手把数据库配置权限一起给出去。
从业务对象建数据模型
先写名词和关系,不先建页面:
用户创建任务,任务产生结果;用户提交订单,支付成功后订单授予权益。
常见对象包括:
- 用户与会话
- 任务或项目
- 用户上传的文件
- 订单、支付尝试和退款
- 权益及其有效期
- 操作日志
每个对象至少要有稳定 ID、创建时间、更新时间和明确状态。
"稳定"的意思是这个 ID 一旦发出去就不会变,也不会被复用。用邮箱或手机号当主键会在用户换号时出问题。
状态不要只用一个布尔值
paid: true 无法表达待支付、支付中、成功、关闭、退款和争议。把重要流程写成有限状态:
订单:待支付 → 支付中 → 已支付 → 已退款
任务:已创建 → 处理中 → 成功 / 失败
权益:未生效 → 有效 → 已到期 / 已撤销状态变化要有触发原因和时间。这样重复回调、人工补单和失败重试才有依据。
一个具体场景:支付回调重复到达三次,你需要知道第二次和第三次应该被忽略。没有状态和时间记录,你只能靠猜。
权益和订单要分开
订单是一次交易记录,权益是用户当前拥有什么。把它们合成一张表,退款和续费都会出问题。
一次退款要做的是:订单状态改成已退款,同时权益状态改成已撤销。这是两个对象的两个变化,需要一起成功或一起失败。
会员和续费的具体处理见订阅与续费。
权限在服务端判断
隐藏按钮不是权限控制。浏览器里的代码和请求都能被用户修改。
每次读取或修改资源时,服务端至少检查:
- 当前身份是谁
- 资源属于谁
- 当前角色或权益是否允许这个动作
- 操作是否处于允许的业务状态
第四条容易漏。"已支付的订单不能再次支付""已撤销的权益不能被使用"这类规则,要写在服务端,不能只靠界面不给入口。
管理操作需要单独记录,不能和普通用户请求混在一起。出事时你需要知道是谁在什么时候改了什么。
涉及金额的一定在服务端算
价格、折扣、额度扣减,全部在服务端计算和校验。
前端传过来的金额只能当成"用户看到的数字",用来对比是否一致,不能当成实际扣款依据。
这条和范围里"不能砍的东西"是同一条。它属于第一版必须做对的少数几件事之一。
处理删除与导出
用户数据不是只能增加。第一版也要知道:
- 用户删除账号时处理哪些关联数据
- 法律或交易记录需要保留哪些部分
- 用户怎样导出自己的关键内容
- 文件删除后备份里会保留多久
无法立即自动化时,可以先建立人工流程,但入口、负责人和完成标准必须明确。
第四条最容易被忽略。用户要求删除数据后,如果备份里还留着三个月,你的隐私说明里就要写清楚这件事。相关做法见隐私与安全。
常见错误
把"已登录"当成权限。 改地址栏里的 ID 就能看到别人数据。
用邮箱或手机号当主键。 用户换号时会出问题。
用一个布尔值表示支付状态。 重复回调和退款都处理不了。
订单和权益合成一张表。 退款和续费会出问题。
权限只靠界面不给入口。 请求可以被直接构造。
金额在前端算。 直接变成资金损失。
管理操作和普通请求混在一起记。 出事时查不出是谁改的。
验收标准
- 画出了"角色 × 资源 × 动作"表,每格写了服务端的检查条件
- 每个带 ID 参数的接口都检查了资源归属
- 关键流程写成了有限状态,状态变化记录了原因和时间
- 订单和权益是两个独立对象
- 所有金额计算和校验都在服务端
- 管理操作有独立的操作日志
- 知道用户要求删除数据时,具体删什么、留什么、备份里留多久
本章动作
画出"角色 × 资源 × 动作"表,为每个允许的操作写出服务端的检查条件。
然后再开始实现登录和会员页面。
下一步
- 微信登录:能不碰就不碰——国内登录方案的选型
- 测试与排错——为权限规则写测试
- 隐私与安全——数据处理的对外承诺