# 5.9 多租户隔离 :::tip 概述 租户隔离是双侧执行的红线:**写侧**全局 Create 钩子补齐 tenant_id,**读侧** repository Scope 追加租户条件。判定依据是 `hooks.tenantTables` 白名单(9 张表),租户状态由租户中间件在请求入口校验。 ::: ## 隔离模型 ```text 平台级(tenantID=0,超管) → 不过滤,全量可见 租户用户 → tenant_id IN (0, 自身租户) (0 为平台级公共数据,租户可见) ``` ## 双侧执行 | 侧 | 执行点 | 行为 | |---|---|---| | 写 | Create 钩子(createStamp) | 租户用户未指定时强制携带自身租户(防跨租户逃逸);超管未指定时取 `tenant.defaultId`,显式传 0 可创建平台共享行 | | 读 | repository Scope(ApplyCtx) | 租户表追加 `tenant_id IN (0, 自身租户)` | 业务代码零参与——只要走 `Ctx(ctx)`,隔离自动生效。 ## 租户白名单(9 张表) ```text gin_user / gin_role / gin_dept / gin_level / gin_position gin_article / gin_category / gin_notice / gin_link ``` **新增租户级表必须同步登记** `internal/model/hooks` 的 tenantTables——漏登记的表写侧不带租户ID、读侧不过滤,等于隔离失效。表还需要真实存在 tenant_id 列。 ## 租户中间件 链位置:JWT 之后、Authz 之前。校验逻辑: ```text 免登录 → 放行 平台级(tenantID=0)→ 放行 租户摘要(缓存 60 秒): 状态非 1(禁用)→ 拒绝 过期时间早于当前 → 拒绝 摘要加载失败 / 加载器未注册 → 放行(降级:不因租户设施故障阻断全部请求) ``` ## 登录时的租户定位 登录请求可带 `tenantCode`:指定时在租户内定位用户;留空时全局匹配(优先平台租户)。租户不存在/禁用/过期分别返回对应业务错误码。 ## 租户管理能力 - 租户 CRUD(gin_tenant,平台级表) - 租户状态启停、有效期管理 - 超管新增租户级数据的默认归属(`tenant.defaultId`) 管理界面见 [6.7 租户管理](/zh/modules/tenant.html)。 ## 设计边界 | 在租户隔离内 | 不在租户隔离内 | |---|---| | 白名单 9 张表的常规读写 | 字典、参数、配置等平台级表 | | 在线用户列表/强退(按租户过滤) | 日志表(审计归属平台) | | 内容模块(文章/分类/公告/友链) | 示例表 gin_example | ## 下一步 → [5.10 数据权限](/zh/core/data-scope.html)