现有Django项目新增FastAPI接口时如何识别并同步认证用户?
整体实现核心思路
1. 认证体系打通方案
- 首选方案:复用Django Session认证(适合前后端同域场景)
Django默认将登录态存在django_session表,sessionid存储在用户HttpOnly Cookie中,FastAPI只需读取请求携带的sessionid,到Django的session表查询校验、解析出用户ID即可完成身份识别。
可直接在FastAPI环境中安装Django依赖,复用原生Session解析逻辑,示例依赖代码如下:
后续FastAPI路由直接依赖该函数即可直接获取Django侧的有效用户对象。from django.contrib.sessions.models import Session from django.contrib.auth import get_user_model from django.conf import settings from fastapi import Request, HTTPException # 配置和Django项目完全一致的参数 settings.configure( SECRET_KEY="你的Django项目原SECRET_KEY", SESSION_ENGINE="django.contrib.sessions.backends.db", INSTALLED_APPS=["django.contrib.sessions", "django.contrib.auth", "django.contrib.contenttypes"] ) import django django.setup() User = get_user_model() async def get_current_user(request: Request): session_id = request.cookies.get(settings.SESSION_COOKIE_NAME) if not session_id: raise HTTPException(status_code=401, detail="未登录") try: session = Session.objects.get(session_key=session_id) if session.is_expired(): raise HTTPException(status_code=401, detail="登录已过期") user_id = session.get_decoded().get("_auth_user_id") return User.objects.get(id=user_id) except (Session.DoesNotExist, User.DoesNotExist): raise HTTPException(status_code=401, detail="认证失败") - 备选方案:JWT认证(适合前后端分离、跨域场景)
Django侧登录成功后签发JWT,JWT中仅存储非敏感的user_id字段,签名密钥和Django的SECRET_KEY保持一致,FastAPI侧用相同密钥校验JWT合法性、解析出用户ID即可完成身份识别。JWT有效期建议设置较短,配合刷新token使用,避免凭证泄露风险。
2. 用户数据安全存储方案
- 用户核心数据(
user_id、username、手机号等)的唯一可信源为Django的auth_user表,禁止在FastAPI侧冗余存储这类可变更的核心字段,避免两边数据不一致。 - 认证凭证必须存储在带
HttpOnly、Secure、SameSite属性的Cookie中,禁止明文存储在前端localStorage/sessionStorage,防止XSS攻击窃取用户身份凭证。 - 如果需要在请求链路中传递用户信息,仅传递
user_id即可,敏感字段禁止在链路中明文传输。
3. 数据库表设计规范
- 所有FastAPI业务表只需新增
user_id字段作为逻辑外键关联Django的auth_user.id,不需要建物理外键约束,避免Django侧用户数据变更影响FastAPI业务稳定性,关联逻辑在业务层自行校验即可。 - 示例业务表结构(以用户待办事项表为例):
CREATE TABLE `fastapi_todo` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', `user_id` int NOT NULL COMMENT '关联Django用户ID', `content` varchar(255) NOT NULL COMMENT '待办内容', `is_done` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否完成', `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`), KEY `idx_user_id` (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='FastAPI待办事项表'; - 若需要存储FastAPI专属的用户扩展属性,可单独建扩展表,仍以
user_id作为关联主键:CREATE TABLE `fastapi_user_extend` ( `user_id` int NOT NULL COMMENT '关联Django用户ID,主键', `last_active_at` datetime DEFAULT NULL COMMENT '最后在FastAPI模块活跃时间', `perm_level` tinyint NOT NULL DEFAULT '1' COMMENT 'FastAPI模块权限等级', `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='FastAPI用户扩展表';
4. 落地注意事项
- 若FastAPI和Django共用数据库,需给FastAPI分配最小权限的数据库账号,仅开放业务表的读写权限,禁止授予
auth_user表的修改权限、全表删除权限,避免误操作影响原有Django线上业务。 - 若两个服务部署隔离、数据库独立,可通过Django提供内部私有接口的方式给FastAPI查询用户基础信息,比直接跨库查询安全性更高。
- 所有FastAPI业务接口都需要校验当前登录用户的
user_id和要操作的数据所属user_id一致,防止越权访问。
内容的提问来源于stack exchange,提问作者Danny
相关产品推荐
相关产品推荐

