news 2026/8/29 1:18:54

跨组织/跨租户权限怎么设计:隔离/共享/委托(附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/8/29 6:21:26

Dify怎么安装:从环境准备到配置完成的完整安装指南

前言 安装Dify是开始AI应用开发的第一步。虽然Dify提供了多种安装方式,但对于初学者来说,选择合适的安装方式并正确配置环境可能会遇到一些挑战。 这篇文章将详细介绍Dify的安装步骤,从环境准备到配置完成,涵盖Docker安装、环境…

作者头像 李华
网站建设 2026/8/29 8:06:26

CI/CD流水线搭建:自动化测试与发布GLM-TTS新版本

CI/CD流水线搭建:自动化测试与发布GLM-TTS新版本 在语音合成技术快速演进的今天,一个模型从实验阶段走向真实业务场景,面临的最大挑战往往不是算法本身,而是如何稳定、高效地完成版本迭代与部署。特别是像 GLM-TTS 这样基于大语言…

作者头像 李华
网站建设 2026/8/21 13:35:49

游戏角色语音包:玩家可自定义NPC对话声音

游戏角色语音包:玩家可自定义NPC对话声音 你有没有想过,有一天可以在游戏里听到自己朋友的声音从某个酒馆老板口中说出?或者让《上古卷轴》里的精灵用你家乡方言念出一句“欢迎来到晨风”?这不再是科幻桥段——借助新一代语音合成…

作者头像 李华
网站建设 2026/8/22 1:05:55

JavaScript前端交互优化:增强GLM-TTS WebUI用户体验

JavaScript前端交互优化:增强GLM-TTS WebUI用户体验 在语音合成技术快速普及的今天,一个强大的AI模型若缺乏直观、流畅的前端界面,其实际应用价值往往会大打折扣。以GLM-TTS为例,这套基于大模型架构的零样本语音克隆系统&#xff…

作者头像 李华
网站建设 2026/8/28 6:13:29

物流状态播报:让用户听到包裹运输进展

物流状态播报:让用户听到包裹运输进展 在快递单号满天飞的今天,你是否曾盯着手机里一条条“您的快件已由【XX分拣中心】发出”的文字通知,看得麻木?这些信息虽然准确,却冰冷、易被忽略。尤其对中老年用户而言&#xff…

作者头像 李华
网站建设 2026/8/22 0:09:55

NPS净推荐值测算:评估GLM-TTS用户的忠诚度水平

NPS净推荐值测算:评估GLM-TTS用户的忠诚度水平 在AI语音技术逐渐渗透到智能客服、有声内容、教育辅助等日常场景的今天,一个核心问题浮出水面:用户真的愿意长期使用并推荐这款TTS产品吗? 技术参数再亮眼——比如支持零样本克隆、情…

作者头像 李华