当前位置: 首页 > news >正文

Django REST Framework 如何配置多租户隔离的 API Token 鉴权?

Django REST Framework 原生不提供多租户 Token 隔离的直接配置项,最稳妥的方案是扩展 Token 模型关联租户信息,并配合自定义认证类或权限类在请求阶段进行校验。

先说结论:DRF 默认认证只校验用户身份,不识别租户上下文,必须通过代码扩展实现逻辑隔离。

  • 适合:需要在一套代码库中服务于多个独立客户或组织群体的 SaaS 场景。
  • 先准备:确定租户模型结构(单独表或用户外键),并规划 Token 与租户的绑定关系。
  • 验收:使用不同租户的 Token 访问同一资源接口,确认无法跨租户读取数据。

核心模型设计

根据业务需求,用户与租户的关系通常有一对一或多对多两种模式。需在模型层明确关联。

1. 一对一模式(用户仅属于一个租户)

class User(AbstractUser):tenant = models.ForeignKey(Tenant, on_delete=models.CASCADE, null=True, blank=True)

2. 多对多模式(用户可属于多个租户)

class User(AbstractUser):tenants = models.ManyToManyField(Tenant, through='UserTenantMembership', blank=True)

如果使用 DRF 自带 Token,建议继承 Token 模型或直接在用户上关联,避免修改核心认证表结构导致升级困难。

认证与权限配置

1. 自定义认证类(基于原生 Token 改造)

标题强调 Token 配置,此处展示如何扩展原生 TokenAuthentication 以校验租户上下文。例如从 Header 中获取租户 ID 并验证用户归属。

from rest_framework.authentication import TokenAuthentication
from rest_framework.exceptions import AuthenticationFailedclass TenantTokenAuthentication(TokenAuthentication):def authenticate(self, request):user, token = super().authenticate(request)# 假设请求头中携带了 X-Tenant-IDtenant_id = request.META.get('HTTP_X_TENANT_ID')if tenant_id:# 根据用户模型关系校验,此处以一对一为例if not user.tenant or str(user.tenant.id) != tenant_id:raise AuthenticationFailed('User not belongs to this tenant')return user, token

2. 自定义权限类(含超级管理员保护)

权限类负责对象级校验,需显式处理超级管理员 bypass 逻辑,避免意外泄露。

from rest_framework import permissionsclass IsTenantMember(permissions.BasePermission):def has_object_permission(self, request, view, obj):# 超级管理员可跨租户查看(根据业务需求决定)if request.user.is_superuser:return True# 假设 obj 是数据对象,且有 tenant 字段return obj.tenant == request.user.tenant

3. settings.py 配置生效

在配置文件中注册自定义类,确保全局生效。

REST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': ['path.to.TenantTokenAuthentication',],'DEFAULT_PERMISSION_CLASSES': ['path.to.IsTenantMember',],
}

数据过滤实现

防止开发者忘记加权限类,建议在 ViewSet 层面做全局过滤。注意:Django 原生 Manager 无法获取 request 对象,不要在 Manager 中尝试获取请求上下文,应在 ViewSet Mixin 中实现。

class TenantFilteredMixin:def get_queryset(self):user = self.request.user# 超级管理员可见所有数据,普通用户仅见本租户if user.is_superuser:return super().get_queryset()return super().get_queryset().filter(tenant=user.tenant)

怎么验证是否生效

不要只在浏览器点一点,要用命令行工具模拟不同租户身份。

1. 准备两个账号

创建属于 Tenant A 和 Tenant B 的两个用户,分别获取他们的 Token。

2. 交叉访问测试

使用 Tenant A 的 Token 请求属于 Tenant B 的数据 ID。例如:

curl -H "Authorization: Token <Tenant_A_Token>" -H "X-Tenant-ID: <Tenant_B_ID>" https://api.example.com/orders/<Tenant_B_Order_ID>/

3. 预期结果

服务器应返回 403 Forbidden 或 404 Not Found(为了隐藏数据存在性,推荐 404)。如果返回了数据,说明过滤逻辑未生效。

4. 检查日志

查看 Django 日志,确认请求是否触发了自定义权限类的检查逻辑。

常见坑

1. 超级管理员权限失控

必须在权限类和过滤逻辑中显式判断 is_superuser,否则管理员可能无法维护数据,或反之绕过隔离。

2. 外键关联遗漏

如果订单关联了产品,产品表如果没有租户字段,可能会导致通过关联表间接泄露其他租户的产品信息。所有涉及业务数据的表都需要评估是否需要租户隔离。

3. 缓存污染

如果使用 Redis 缓存接口数据,Cache Key 必须包含租户 ID。否则租户 A 可能命中租户 B 的缓存数据。例如 Key 设计为 order_list:{tenant_id}:{page}

4. 第三方包兼容性

某些 DRF 扩展包(如导出、导入功能)可能直接使用模型.objects.all(),绕过你的 ViewSet 过滤逻辑。需要检查这些功能的源码或进行 Hook 修改。

参考来源

  • Django REST Framework - Authentication: https://www.django-rest-framework.org/api-guide/authentication/
  • Django REST Framework - Permissions: https://www.django-rest-framework.org/api-guide/permissions/

原文链接:https://www.zjcp.cc/ask/11356.html

http://www.jsqmd.com/news/835036/

相关文章:

  • 南京除甲醛公司避坑指南:全国直营才是真保障 - 博客湾
  • 软件开发与创新课程设计第11周作业——主流原型设计工具的介绍与对比
  • 长沙除甲醛公司水有多深?全国直营vs加盟等三种模式一次讲透 - 博客湾
  • 从 cursor 、 Claude code 迁移到 codex,30 分钟快速上手 codex 常用技巧
  • MATLAB实现:基于图像对比度和波段相关性的高光谱波段选择算法
  • 2026平遥本地餐厅排行:平遥古城晋菜门店实测对比 - 奔跑123
  • 昇腾AOE调优引擎
  • 成都除甲醛公司深度解析 分清直营优劣避开行业乱象 - 博客湾
  • Shell编程 - dialog 程序使用指南
  • 长沙除甲醛公司深度测评:直营与加盟的五大评判标准 - 博客湾
  • 西安除甲醛公司实测解析:商业模式拆解与避坑选购指南 - 博客湾
  • 郑州除甲醛市场真相:三类公司怎么选?别再被“全国直营”话术忽悠了 - 博客湾
  • 南京除甲醛服务公司选择指南:从评判标准到模式解析 - 博客湾
  • 昇腾应用部署实践
  • 宁波奢侈品钻石首饰回收实体店评测 二手钻戒项链首饰回收报价行情分享 - 博客湾
  • 郑州除甲醛公司真相:别被“百城直营”忽悠,看懂模式才算真懂行 - 博客湾
  • Ascend C 新一代算子编程语言
  • 2026年|拒绝智商税!亲测5款降AI工具,谁才是过知网的真正救星? - 降AI实验室
  • 昇腾性能分析工具体系
  • 昇腾框架适配层
  • 2026春招薪资陆续开奖:大厂应届生待遇,到底拉开了多大差距?
  • 如何在 Nginx Lua 脚本中实现 HMAC 签名验签 API 鉴权?
  • 西安除甲醛公司怎么选?三大硬核标准识破“伪直营”套路 - 博客湾
  • MindSpore 与 PyTorch 在昇腾上的开发
  • # 2026年GEO优化服务商推荐:按企业需求场景选择合作伙伴的决策指南 - 科技焦点
  • 郑州除甲醛公司避坑:直营、伪直营与加盟的本质区别 - 博客湾
  • 苏州除甲醛公司怎么选:别被“百城直营”四个字带走节奏 - 博客湾
  • 昇腾算子开发体系
  • 《觉醒时刻:AI Agent引爆企业效率革命》第一章
  • 2026年|Turnitin查出AIGC率爆表?3个亲测有效方法教你高效去AI痕迹,附官方检测报告! - 降AI实验室