网易首页 > 网易号 > 正文 申请入驻

SaaS多租户数据隔离:一个忘写的WHERE子句如何毁掉周一早晨

0
分享至

你刚做SaaS三个月,客户开始要报表。第一家客户Acme Corp想看到自己的订单、注册量和收入。你随手写了个WHERE tenant_id = 42就上线了。

六个月后,400个租户、30套报表、一个能自动生成SQL的AI助手,还有某个周二早晨忘记写WHERE子句的工程师。现在Acme Corp能看到Globex的数据。这种周一早晨的头条新闻,你绝对不想上。


这篇文章讲如何架构多租户SQL报表系统,让单个遗漏的子句永远不会变成数据泄露。涉及租户schema设计、Postgres行级安全(RLS)、JWT对接、性能索引,以及生产环境里坑过无数人的陷阱。


先选隔离模型,再写任何SQL。三种经典方案:

共享schema + tenant_id列——90%的SaaS该选这个。便宜、能扩展,Postgres自带工具保安全。下文默认这个模式。

第一步:每行打上tenant_id标签

存客户数据的表全都要有租户标识符,没有例外。eventsaudit_logsai_query_history这些表也一样。

注意两点:tenant_id设为NOT NULL(空值意味着孤儿行会绕过过滤),索引把tenant_id放最前面。所有报表查询都按租户过滤,这就是你的核心索引。

第二步:用行级安全当兜底

应用层过滤没问题,直到有人忘记写。Postgres RLS在数据库层强制执行过滤,就算裸跑SELECT * FROM orders,返回的也只是当前租户有权查看的行。

USING子管你能读哪些行,WITH CHECK子句防止你往其他租户插入或更新数据。两个方向都堵住。

现在每个连接必须先设app.tenant_id再查:

SET LOCAL把设置绑定到当前事务,连接池里的请求不会串号——这点很重要。

第三步:把租户上下文接到认证层

设置值必须来自可信源。标准做法是从验签过的JWT里提取:


应用启动事务时,从JWT解出tenant_id,执行SET LOCAL,后续所有查询自动带租户隔离。就算ORM或AI生成的SQL漏了WHERE子句,RLS也会拦截越权访问。

性能:索引策略

RLS有开销。Postgres会对每行检查策略,大表可能变慢。关键优化:

• 复合索引把tenant_id放首位,覆盖最常见的查询模式

• 避免在RLS策略里放复杂函数,尽量直接比较

• 用EXPLAIN ANALYZE验证查询计划,确认索引被用上

生产环境的坑

连接池+RLS的交互容易出事。SET LOCAL只在事务内有效,但某些池化配置会复用连接而不重置状态。务必测试边界情况:事务中途报错、连接超时、强制回滚后的状态。

另一个陷阱:备份和ETL流程。这些工具通常用超级用户连接,默认绕过RLS。要么给它们专门的用户角色并启用RLS,要么在导出前显式过滤数据。

还有AI生成SQL的场景。LLM可能"聪明"地试图优化查询,比如把tenant_id条件改写成子查询或JOIN。只要最终执行时app.tenant_id已设置,RLS仍然生效——但调试会变得很头疼,因为生成的SQL看起来和你预期的不一样。

最后,测试。不是测"正常情况能工作",而是测"WHERE子句被删掉时会不会泄露数据"。自动化测试里专门写几个故意漏掉tenant过滤的查询,验证RLS确实拦截。

多租户数据隔离没有银弹。共享schema+RLS是性价比最高的方案,但前提是每一步都踩实:schema设计、索引策略、JWT对接、连接池配置、测试覆盖。任何一个环节偷懒,那个忘写WHERE子句的周二早晨就会找上门。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
一座天坛,横跨51年:美国总统再次踏上中美交往的历史现场

一座天坛,横跨51年:美国总统再次踏上中美交往的历史现场

澎湃新闻
2026-05-14 13:34:30
特朗普走下车一瞬间,一只喜鹊忽然从天而降,稳稳的落在了旁边

特朗普走下车一瞬间,一只喜鹊忽然从天而降,稳稳的落在了旁边

漫川舟船
2026-05-14 16:49:29
看是御姐,脸还能打,肉却 “软趴趴” 了

看是御姐,脸还能打,肉却 “软趴趴” 了

飛娱日记
2026-03-13 11:31:29
释永信被一女子爆料:她们姐妹住少林寺3天,争着往释永信房间跑

释永信被一女子爆料:她们姐妹住少林寺3天,争着往释永信房间跑

江山挥笔
2026-03-23 15:40:31
白鹿迎来全网骂潮,是因为她踩中了,中国观众最讨厌的3个雷区

白鹿迎来全网骂潮,是因为她踩中了,中国观众最讨厌的3个雷区

阿凫爱吐槽
2026-05-14 02:15:54
一个地方官员看追觅“崩老头”

一个地方官员看追觅“崩老头”

无忌财谈
2026-05-13 20:32:36
河北一火锅店发生刑案,当地警方:36岁男子因琐事持刀杀害46岁女子,已被刑拘,请广大网民不信谣、不传谣

河北一火锅店发生刑案,当地警方:36岁男子因琐事持刀杀害46岁女子,已被刑拘,请广大网民不信谣、不传谣

都市快报橙柿互动
2026-05-14 14:56:31
河南一家公司员工上班借给公司128万,其中2名男子帮老板担保贷80万,现在名下财产被查封;公司老板:将与银行协商,尽可能不牵扯到员工

河南一家公司员工上班借给公司128万,其中2名男子帮老板担保贷80万,现在名下财产被查封;公司老板:将与银行协商,尽可能不牵扯到员工

潇湘晨报
2026-05-14 13:08:12
没有美国,泽连斯基为何依然能赢得战争?

没有美国,泽连斯基为何依然能赢得战争?

高博新视野
2026-05-14 07:30:18
【社论】中国AI企业背后的创新密码

【社论】中国AI企业背后的创新密码

澎湃新闻
2026-05-13 17:08:27
热刺已追平上赛季积分,还剩两轮比赛

热刺已追平上赛季积分,还剩两轮比赛

懂球帝
2026-05-14 15:58:14
哈佛提醒:防肌肉流失别只补蛋白!这6种营养才是关键

哈佛提醒:防肌肉流失别只补蛋白!这6种营养才是关键

橘子约定
2026-05-05 20:49:53
美国万万没想到,别国军备是为了打仗,中国军工却为以防万一?

美国万万没想到,别国军备是为了打仗,中国军工却为以防万一?

栗子熟了呀
2026-05-14 08:37:30
炸了!奥尼尔评 NBA 历史前十巨星 詹皇仅第 3

炸了!奥尼尔评 NBA 历史前十巨星 詹皇仅第 3

澜归序
2026-05-14 04:07:21
刘震云:如果你一听到伴侣说话就烦躁,有股无名火,真正的原因不是你讨厌他,也不是你脾气不好,而是条件反射

刘震云:如果你一听到伴侣说话就烦躁,有股无名火,真正的原因不是你讨厌他,也不是你脾气不好,而是条件反射

脆皮先生
2026-05-13 19:42:42
华谊兄弟得罪了这个大佬

华谊兄弟得罪了这个大佬

蓝钻故事
2026-05-13 15:35:51
四级应急响应!江苏,大暴雨要来了!

四级应急响应!江苏,大暴雨要来了!

南通攻略
2026-05-14 10:46:58
因违反金融统计管理规定 浙江开化农商行被罚290.09万元

因违反金融统计管理规定 浙江开化农商行被罚290.09万元

IPO参考
2026-05-14 09:42:17
突发新政!事关南京全体小区业主!

突发新政!事关南京全体小区业主!

住在南京
2026-05-14 12:34:23
马斯克2个月连发26条种族帖,只为攻击诺兰2.5亿新片选角

马斯克2个月连发26条种族帖,只为攻击诺兰2.5亿新片选角

热搜摘要官
2026-05-14 06:45:33
2026-05-14 17:23:00
摸鱼算法
摸鱼算法
致力于用最前沿的AI技术,换取更多发呆时间的三十岁青年。
2731文章数 26关注度
往期回顾 全部

科技要闻

马斯克说会谈很顺利 黄仁勋点赞 库克比耶

头条要闻

重庆一栋百年古建筑以399万公开拍卖 仅限中国人竞买

头条要闻

重庆一栋百年古建筑以399万公开拍卖 仅限中国人竞买

体育要闻

登海报!哈登30+8+6创多项纪录 第8次赢天王山

娱乐要闻

何九华官宣当爸!全程不提孩子妈

财经要闻

习近平同美国总统特朗普会谈

汽车要闻

新时代传统豪华是什么样? 上汽奥迪E7X给出了自己的答案

态度原创

教育
时尚
家居
本地
公开课

教育要闻

华罗庚竞赛题,解法太巧妙了,学霸想不到

T恤+低腰阔腿裤、衬衫+低腰半裙,今年夏天最时髦的搭配,谁穿谁好看!

家居要闻

精神奢享 对话塔尖需求

本地新闻

用苏绣的方式,打开江西婺源

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版