1、权限隔离的底层逻辑:为什么接口适配中必须做权限隔离?
说实话,我见过太多系统在接口适配阶段栽跟头了。
明明单体应用里跑得好好的,一拆成微服务,一对接第三方,权限就乱成一锅粥。有人能跨系统删数据,有人能看到不该看的报表,更离谱的是——测试账号居然在生产环境有管理员权限。
这些问题的根子,都在于接口适配时没做权限隔离。
1.1 先搞清楚:什么是接口适配中的权限隔离?
接口适配,说白了就是两个系统之间互相喊话。A系统说「我要查订单」,B系统得先确认:你是谁?你能查吗?你能查哪些?
权限隔离就是在这条通话线路上,加一道严格的安检门。每个请求进来,都得验明正身,按权限放行。
我习惯把权限隔离拆成三层来看:
- 身份层:确认调用方是谁(系统身份还是用户身份)
- 授权层:确认调用方有没有权限做这个操作
- 数据层:确认调用方只能看到自己该看的数据
这三层缺一不可。我在项目中遇到过,有的团队只做了身份层,授权层直接放行,结果一个普通用户通过接口拿到了管理员的数据——这就是典型的「有认证无授权」。
1.2 为什么接口适配中必须做权限隔离?
你想想看,接口适配和单体应用最大的区别是什么?
单体应用里,所有代码跑在一个进程里,权限检查可以靠内存共享、靠线程上下文。但接口适配不一样——每次调用都是一次网络请求,调用方可能是你的前端、另一个微服务、甚至是第三方公司的系统。
我总结了几条必须做的理由:
| 场景 | 不做隔离的后果 | 真实案例 |
|---|---|---|
| 内部服务间调用 | 一个服务被攻破,所有服务沦陷 | 某电商公司订单服务被注入,通过内部API删光了用户数据 |
| 第三方系统对接 | 对方可以越权操作你的核心资源 | 某支付渠道接口没做隔离,合作方能看到其他商户的交易记录 |
| 多租户场景 | 租户A能看到租户B的数据 | 某SaaS平台接口适配时漏了租户ID校验,数据全部串了 |
| 前后端分离 | 前端可以随意调用后端任意接口 | 某后台管理系统,前端直接调了删除接口,没有权限校验 |
说白了,接口适配就是系统的「国境线」。你不设关卡,别人就能长驱直入。
1.3 核心原则一:最小权限
这个原则听起来简单,做起来最难。
最小权限的意思是:每个调用方只给刚刚够用的权限,多一点都不给。
举个例子。你的订单服务需要调用用户服务查一下用户姓名。按最小权限原则:
- 不能给「查询全部用户信息」的权限
- 不能给「修改用户信息」的权限
- 只能给「根据用户ID查询用户姓名」这个接口的权限
我曾经接手过一个项目,内部服务之间全部用的超级管理员Token。问为什么?「方便啊,省得配权限麻烦。」结果呢?一个本应只读的报表服务,因为用了超级Token,被人利用删了生产数据库。
我曾经犯过一个错:给第三方系统分配了「查询订单」的权限,但没限制查询范围。结果对方写了个脚本,遍历订单ID,把全平台半年的订单数据全拉走了。后来我学乖了——最小权限不仅要限制「能做什么」,还要限制「能做多少」。
1.4 核心原则二:职责分离
职责分离,就是不能让同一个人或同一个系统同时拥有两种冲突的权限。
比如:
- 下单的人和审批订单的人不能是同一个
- 写数据和审计数据的人不能是同一个
- 配置接口权限和调用接口的人不能是同一个
在接口适配中,职责分离体现在哪里?
我举个例子。你的支付系统对接了财务系统。支付系统负责生成账单,财务系统负责对账。如果支付系统同时拥有「生成账单」和「修改账单」的权限,那它就能伪造账单、掩盖问题。
正确的做法是:
// 错误:一个接口同时提供读写能力
POST /api/bill
{
"action": "create_or_update", // 既能创建又能修改
"billId": "123",
"amount": 1000
}
// 正确:读写分离
POST /api/bill/create // 只负责创建
POST /api/bill/update // 需要额外审批权限
嗯,这里要注意。职责分离不是死板的。小团队里一个人干多个角色很正常,但接口层面必须分开——你可以是一个人,但必须用两把不同的钥匙。
1.5 核心原则三:纵深防御
纵深防御,就是别把鸡蛋放在一个篮子里。
很多团队只在网关层做一次权限校验,觉得够了。但你想过没有——网关被绕过了怎么办?内部服务之间直接调用了怎么办?
我习惯的做法是分层设防:
| 层级 | 做什么 | 防什么 |
|---|---|---|
| 网关层 | 校验Token、白名单、限流 | 外部非法请求、DDoS |
| 服务层 | 校验调用方身份、接口权限 | 内部越权调用、Token泄露 |
| 数据层 | 行级权限、字段级脱敏 | 数据越权访问、SQL注入 |
每一层都假设「上一层已经被攻破了」。网关校验过了,服务层还得再校验一次;服务层校验过了,数据层还得再过滤一次。
纵深防御不是让你写三遍重复代码。网关层做粗粒度校验(比如「这个接口需要登录」),服务层做细粒度校验(比如「这个用户只能查自己的订单」),数据层做兜底校验(比如「WHERE user_id = ?」)。三层各司其职,互不替代。
1.6 一张图看懂权限隔离的底层逻辑
下面这张图,是我做接口权限设计时必画的框架。它把三个原则串在了一起:
1.7 小结:三个原则怎么配合?
这三个原则不是孤立的,它们是一个整体。
- 最小权限告诉你「给多少」——给最少的,够用就行
- 职责分离告诉你「怎么分」——把权力拆开,互相制衡
- 纵深防御告诉你「怎么防」——层层设卡,别指望一道墙
我见过最好的权限隔离设计,是三个原则同时起作用。比如一个订单查询接口:
- 最小权限:只给「查询本租户近30天订单」的权限,不给导出、不给删除
- 职责分离:查询接口和审批接口用不同的API Key,一个人不能同时拥有
- 纵深防御:网关校验Token → 服务层校验租户ID → 数据库层WHERE条件过滤
这样设计下来,就算某个环节出了漏洞,其他环节还能兜住。
接口适配中的权限隔离,不是「做不做」的问题,而是「做到什么程度」的问题。三个原则缺一个,你的系统就多一个被攻破的可能。