news 2026/4/22 12:49:34

跨组织/跨租户权限怎么设计:隔离/共享/委托(附SaaS权限模板)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
跨组织/跨租户权限怎么设计:隔离/共享/委托(附SaaS权限模板)

前言

多租户是SaaS系统的核心特性。很多SaaS系统的数据泄露都是因为租户隔离没做好。这篇给你多租户权限的3种策略+完整设计方法。

一、3种多租户策略

策略特点适用场景优点缺点
完全隔离每个租户独立数据库高安全要求安全性高成本高
共享隔离共享数据库,tenant_id隔离通用SaaS成本低需严格校验
混合模式核心数据隔离,其他共享平衡安全与成本灵活复杂度高

二、共享隔离模式(推荐)

核心原则

  • 所有数据表必须有tenant_id字段
  • 所有查询必须带WHERE tenant_id = 当前租户ID
  • 跨租户访问返回403

实现步骤

步骤1:数据表设计

所有业务表必须包含tenant_id字段,并建立索引。

订单表(orders)示例: CREATE TABLE orders ( id BIGINT PRIMARY KEY AUTO_INCREMENT, tenant_id BIGINT NOT NULL COMMENT '租户ID', user_id BIGINT NOT NULL COMMENT '用户ID', order_no VARCHAR(32) NOT NULL COMMENT '订单号', amount DECIMAL(10,2) NOT NULL COMMENT '订单金额', status VARCHAR(20) NOT NULL COMMENT '订单状态', created_at DATETIME NOT NULL, INDEX idx_tenant_id (tenant_id), INDEX idx_tenant_user (tenant_id, user_id) ) COMMENT='订单表'; 注意: - tenant_id必须NOT NULL - 在tenant_id上建立索引,提高查询性能 - 联合索引(tenant_id, user_id)支持按租户和用户查询
步骤2:租户ID获取

从用户登录信息中获取tenant_id,不能从请求参数中获取。

伪代码示例: // 从JWT Token中获取租户ID function getTenantId(request) { const token = request.headers.authorization; const decoded = jwt.decode(token); return decoded.tenant_id; // 从token中获取,不能从参数获取 } // 从Session中获取租户ID function getTenantIdFromSession(request) { return request.session.user.tenant_id; // 从session中获取 }
步骤3:查询自动过滤

在数据访问层统一添加tenant_id过滤条件。

伪代码示例: // 数据访问层统一处理 function getOrders(user, filters) { let query = "SELECT * FROM orders"; let where = []; // 自动添加tenant_id过滤 where.push("tenant_id = " + user.tenant_id); // 添加其他过滤条件 if (filters.status) { where.push("status = '" + filters.status + "'"); } if (where.length > 0) { query += " WHERE " + where.join(" AND "); } return executeQuery(query); } // 平台管理员特殊处理 function getOrdersForAdmin(admin, filters) { let query = "SELECT * FROM orders"; let where = []; // 平台管理员不添加tenant_id过滤,但可以指定租户 if (filters.tenant_id) { where.push("tenant_id = " + filters.tenant_id); } if (where.length > 0) { query += " WHERE " + where.join(" AND "); } return executeQuery(query); }
步骤4:跨租户访问校验

在接口层校验数据归属,防止跨租户访问。

伪代码示例: // 接口层校验 app.get('/api/orders/:id', async (req, res) => { const order = await getOrderById(req.params.id); const userTenantId = req.user.tenant_id; // 校验租户归属 if (order.tenant_id !== userTenantId && req.use
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/19 2:38:45

免费试用+增值服务模式:吸引用户购买GPU计算资源

免费试用增值服务模式:吸引用户购买GPU计算资源 在AI语音技术飞速发展的今天,我们已经不再满足于“能说话”的机器。从智能客服到有声读物,从虚拟主播到个性化语音助手,市场对语音合成(TTS)的要求早已超越基…

作者头像 李华
网站建设 2026/4/17 15:13:37

app.py入口文件分析:理解GLM-TTS Web服务运行机制

GLM-TTS Web服务运行机制解析:从app.py看AI语音系统的工程化落地 在生成式AI迅猛发展的今天,语音合成技术早已不再局限于实验室中的“能说会道”,而是朝着个性化、情感化和即用化的方向快速演进。尤其是零样本语音克隆(Zero-shot …

作者头像 李华
网站建设 2026/4/21 23:05:36

API文档撰写规范:清晰易懂地说明GLM-TTS接口用法

API文档撰写规范:清晰易懂地说明GLM-TTS接口用法 在智能语音应用日益普及的今天,用户不再满足于“能说话”的机器,而是期待更自然、有情感、个性化的语音交互体验。从虚拟主播到个性化有声书,从教育配音到多语言内容生成&#xff…

作者头像 李华
网站建设 2026/4/18 4:34:18

栈溢出攻击原理与防御

栈溢出攻击原理与防御 栈的结构与特性 栈(Stack)是用于存储函数调用过程中局部变量、参数、返回地址以及保存的寄存器值的内存区域。每次函数调用时,系统会在栈上分配一个栈帧。栈的生长方向是从高地址向低地址,而缓冲区数据的写入…

作者头像 李华
网站建设 2026/4/21 16:57:21

安装包打包规范:为GLM-TTS制作一键部署发行版

安装包打包规范:为GLM-TTS制作一键部署发行版 在语音合成技术飞速演进的今天,一个令人兴奋的趋势正在发生:我们不再需要为每个说话人重新训练模型,也能生成高度逼真的个性化语音。GLM-TTS 正是这一趋势下的代表性成果——它基于大…

作者头像 李华
网站建设 2026/4/21 13:26:22

元宇宙应用场景:在VR环境中使用个性化语音合成

元宇宙中的声音人格:VR环境下的个性化语音合成实践 在虚拟现实(VR)世界中,当你的数字分身第一次开口说话——是机械单调的合成音,还是带着你真实语调、情绪起伏的声音?这个看似微小的差异,恰恰决…

作者头像 李华