只要服务端项目对外开放,认证与权限几乎就绕不过去。真正难的地方从来不是会不会签发 token,而是知道用户身份、会话状态、权限判定和安全边界分别应该落在哪一层。这一篇会把认证与授权主线系统串起来。
认证和授权为什么不是一回事?
很多人会把“登录”和“权限”混着说,但它们解决的是不同问题:
- 认证回答的是“你是谁”;
- 授权回答的是“你能做什么”。
这两者高度相关,但不能混成同一个概念。只要边界不清楚,系统后面就很容易出现:
- 登录了却还能越权;
- 角色判断和身份判断写在一起;
- 某些接口到底是没登录,还是没权限,表达不清。
Session 和 JWT 到底怎么选?
它们本质上都是在解决“如何让后续请求持续携带身份状态”这个问题,只是策略不同。
Session 更强调服务端保存会话状态,因此更容易集中控制、失效和管理;JWT 更强调令牌自描述与跨服务携带能力,因此在某些分布式和前后端分离场景里会更灵活。
真正的选型重点不是跟风,而是看你的系统更在意什么:
- 更强的服务端控制力;
- 还是更灵活的无状态协作;
- 更简单的失效管理;
- 还是更方便的跨边界传递。
也就是说,它们的差异不在于“谁更先进”,而在于状态由谁掌握、失效如何传播、系统边界如何协作。只要这几点想不清楚,选型讨论就很容易停留在表面印象。
权限模型到底该怎么理解?
权限控制真正难的地方,不是写一个 if 判断,而是定义边界。最常见的模型之一是 RBAC,也就是基于角色的权限控制。它的优势在于简单、直观、适合很多后台系统。
但随着业务复杂度上升,你很快会发现,仅仅有角色还不够。因为现实问题经常变成:
- 这个人虽然是某个角色,但只能操作自己范围内的数据;
- 某个动作并不是看角色,而是看资源归属和状态;
- 权限需要细到字段、操作或条件层级。
这说明权限设计本质上是业务边界设计,而不是单一中间件问题。
更成熟的权限设计,往往会把几个层次拆开看:
- 是否已登录;
- 是否具备某类角色或能力;
- 是否对当前资源拥有操作范围;
- 当前资源状态是否允许执行该动作。
当这些层次被混成一个 if 判断时,系统一开始可能还能跑,但很快就会在边界条件下变得难以解释。
常见安全问题为什么总是反复出现?
因为很多安全问题看起来像低级错误,但本质上都和边界意识不足有关。比如:
- 只验证身份,不验证资源归属;
- token 泄漏后没有合理失效策略;
- 敏感接口缺少额外保护;
- 错误信息暴露太多内部细节;
- 默认把客户端传来的身份信息当真。
所以,安全很多时候不是“高级专题”,而是日常接口设计是否认真。
除此之外,认证与权限还有几个很容易被忽略的操作性问题:
- 登出或权限变更后,旧状态多久失效;
- 多端登录时,会话是否需要互斥或可管理;
- 敏感操作是否需要二次确认或更短期的凭证;
- 权限拒绝时,错误响应是否既明确又不过度暴露内部信息。
这些都不是锦上添花,而是系统进入真实使用后迟早会遇到的问题。
一个更稳妥的认证与授权链路应该长什么样?
如果把这件事收拢成一条最小闭环,通常至少要做到:
- 先清楚区分认证和授权;
- 选定
Session或JWT时明确状态管理策略; - 把角色判断和资源级权限判断区分开;
- 对敏感接口补足失效、续期和异常处理策略;
- 默认把客户端输入当作不可信,再逐层验证。
总结
这一篇我们把身份认证和权限控制从“登录功能”提升成了一整条系统设计主线:认证负责确认身份,授权负责限制能力,Session 和 JWT 只是两类不同实现策略,而真正的风险则往往藏在资源边界和安全细节里。
下一篇我们会进入服务端另一个很常见、也很容易留下隐患的能力,也就是文件上传与静态资源处理。