首页
/ FastAPI 响应 Cookie 实战:用 Response 参数与直接返回 Response 设置 Set-Cookie

FastAPI 响应 Cookie 实战:用 Response 参数与直接返回 Response 设置 Set-Cookie

2026-09-05 12:31:31作者:董宙帆

本文基于 FastAPI 官方文档《Response Cookies》(docs/de/docs/advanced/response-cookies.md),讲解在 API 响应中设置 Cookie 的两种标准做法:在路径操作函数中声明 Response 参数写入 Cookie,以及直接构造并返回一个 Response 对象。结合仓库源码,还会说明 FastAPI 内部如何把"临时响应"上的 Cookie、Header 与状态码合并进最终响应,帮助你在生产接口中正确、安全地管理会话 Cookie。

方式一:声明 Response 参数(推荐)

你可以直接在路径操作函数中声明一个类型为 Response 的参数,这个对象是一个临时响应(temporary response),你可以在其中调用 set_cookie() 设置 Cookie:

from fastapi import FastAPI, Response

app = FastAPI()


@app.post("/cookie-and-object/")
def create_cookie(response: Response):
    response.set_cookie(key="fakesession", value="fake-cookie-session-value")
    return {"message": "Come to the dark side, we have cookies"}

完整可运行示例见 docs_src/response_cookies/tutorial002_py310.py

设置完 Cookie 后,函数仍可以像平常一样返回任意对象(dict、数据库模型等);如果声明了 response_model,它依然会用于过滤和转换你返回的对象。

FastAPI 的工作机制是:把你在临时 Response 上设置的 Cookies(以及 Headers、状态码)提取出来,合并进最终响应——最终响应的 body 则是经过 response_model 过滤后、你实际返回值序列化得到的内容。

另外,Response 参数同样可以在依赖项(dependency)函数中声明,从而在依赖里集中设置 Cookie 和 Header,这对"登录依赖自动下发会话 Cookie"这类横切逻辑非常实用。

源码印证:临时 Response 从哪里来、如何被合并

从源码结构看,这条机制可以在仓库中完整追踪到:

  1. 临时 Response 的创建:在依赖求解阶段,solve_dependencies 在外部未传入 response 时会新建一个空 Response(),并主动删除其 content-length 头、把 status_code 置为 None(见 fastapi/dependencies/utils.py)。这个对象会被注入进路径操作函数(或依赖函数)的 Response 形参,同时挂在 SolvedDependency.response 字段上(fastapi/dependencies/utils.py),最终随 solved_result 传递到路由处理层。

  2. 最终响应的组装:路由层的 get_request_handler 在执行完端点函数后,对非 Response 返回值先走 serialize_response()response_model 过滤序列化,然后执行关键的一行:response.headers.raw.extend(solved_result.response.headers.raw)fastapi/routing.py)——临时响应上累积的 set-cookie 头正是通过这里被原样合并进最终响应。

  3. 状态码优先级_build_response_args 显示,若临时响应上被设置了状态码,它会覆盖装饰器里声明的默认状态码,因此你可以在依赖或端点里用 response.status_code = 201 动态调整响应状态。

测试用例 tests/test_tutorial/test_response_cookies/test_tutorial002.py 验证了该用法:POST 请求后断言 response.cookies["fakesession"] == "fake-cookie-session-value" 且 body 仍是普通 JSON 对象,证明 Cookie 与 body 序列化互不干扰。

方式二:直接返回一个 Response 对象

你也可以在代码中直接构造一个 Response 对象,设置 Cookie 后原样返回。做法是先按"直接返回 Response"的常规方式创建响应(可参考 docs_src/response_directly/tutorial001_py310.py 的写法),再对其实例调用 set_cookie()

from fastapi import FastAPI
from fastapi.responses import JSONResponse

app = FastAPI()


@app.post("/cookie/")
def create_cookie():
    content = {"message": "Come to the dark side, we have cookies"}
    response = JSONResponse(content=content)
    response.set_cookie(key="fakesession", value="fake-cookie-session-value")
    return response

完整示例见 docs_src/response_cookies/tutorial001_py310.py

注意:直接返回 Response 会跳过 response_model 过滤

文档中特别提示(tip):如果你直接返回 Response 而不是使用 Response 参数,FastAPI 会原样直接返回它,不做任何 response_model 过滤。因此你必须自行保证:

  • 数据是正确类型——例如返回 JSONResponse 时,body 内容必须与 JSON 兼容;
  • 没有把本应被 response_model 过滤掉的敏感数据(如内部字段)泄漏到响应中。

源码印证:get_request_handler 中有明确的分支——if isinstance(raw_response, Response) 时直接把返回值作为最终响应(仅在未设置后台任务时补上 solved_result.background_tasks),完全不经过 serialize_response() 的模型过滤流程。这也是两种写法在安全性上的本质区别,选择时应优先考虑 Response 参数方式。

更多说明:fastapi.Responsefastapi.responses 的来源

关于 Response 类的导入,文档给出了如下技术细节:

  • 你也可以写 from starlette.responses import Responsefrom starlette.responses import JSONResponse,效果相同;
  • FastAPI 只是把 starlette.responses 原样以 fastapi.responses 的名字再提供一遍,方便开发者;大部分可用的 Response 类实际上直接来自 Starlette;
  • 而因为 Response 常被用来设置 Header 和 Cookie,FastAPI 还额外把它单独暴露为 fastapi.Response,即 from .responses import Response as Response,所以你既可以从 fastapi import Response,也可以从 fastapi.responses import Response

set_cookie() 的完整参数

set_cookie() 是 Starlette 提供的实例方法,除 keyvalue 外还支持 Cookie 规范中的常见属性:max_age(有效期秒数)、expires(过期时间)、path(作用路径)、domain(作用域)、secure(仅 HTTPS)、httponly(禁止 JavaScript 访问,防范 XSS 窃取会话)、samesitelax/strict/none,防范 CSRF 场景)。完整参数与取值说明请查阅 Starlette 官方文档的 set-cookie 章节。

从会话安全实践角度,设置会话类 Cookie 时通常建议同时指定 httponly=Truesecure=True,并配合 samesite="lax";FastAPI 本身只负责把 Cookie 头写进响应,策略由你在调用 set_cookie() 时决定。

小结与验证方式

两种方案的选择依据很清晰:

场景 推荐做法 关键文件
端点还要返回数据、且使用了 response_model 声明 Response 参数 tutorial002_py310.py
需要完全自定义响应体/状态码/Content-Type 直接构造并返回 Response tutorial001_py310.py
在依赖中统一下发 Cookie(如会话、语言偏好) 依赖函数中声明 Response 参数 fastapi/dependencies/utils.py

本地验证方式:运行 uvicorn 启动对应 docs_src/response_cookies 示例,用 curl 发 POST 请求即可在响应头中看到 set-cookie: fakesession=fake-cookie-session-value; Path=/;或直接运行仓库自带的测试 tests/test_tutorial/test_response_cookies/test_tutorial001.pytest_tutorial002.py 观察断言行为。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
588
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
906
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
891
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.53 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.34 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
987
504
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384