首页
/ FastAPI Cookie 参数(Cookie Parameters)声明指南:从基础用法到源码级解析

FastAPI Cookie 参数(Cookie Parameters)声明指南:从基础用法到源码级解析

2026-09-07 18:18:38作者:申梦珏Efrain

读取 HTTP Cookie 并向路径操作函数注入其值,是开发登录态、会话与广告追踪等场景的常见需求。本文围绕 FastAPI 官方教程中的 Cookie 参数篇章(对应文档 docs/hi/docs/tutorial/cookie-params.md 及英文版 docs/en/docs/tutorial/cookie-params.md),完整讲解如何像声明 QueryPath 参数一样声明 Cookie 参数,并结合仓库内 fastapi/params.pyfastapi/param_functions.py 等源码解释其底层原理。读完本文,你将掌握 Cookie() 的正确导入与声明姿势、可选的默认值与校验参数、为何必须显式使用 Cookie,以及浏览器与 Swagger UI 对 Cookie 的特殊行为。

为什么需要声明式地读取 Cookie

在 HTTP 协议中,客户端(通常是浏览器)会通过 Cookie 请求头把一系列 key=value 键值对随请求发送给服务端。在没有声明式框架辅助时,开发者需要手动从 Request 对象中解析请求头、按分隔符拆分再逐个取值——繁琐且容易出错。

FastAPI 提供的思路非常直接:Cookie 参数的声明方式与查询参数 Query、路径参数 Path 完全同构。只要把函数参数标注为 Cookie 类型,FastAPI 的依赖注入系统就会自动帮你完成 Cookie 的提取、类型转换与校验,你只需关注业务逻辑本身。

导入 Cookie

使用 Cookie 参数的第一步是从 fastapi 中导入 Cookie

from typing import Annotated

from fastapi import Cookie, FastAPI

app = FastAPI()

对应官方教程示例文件为 docs_src/cookie_params/tutorial001_an_py310.py(基于 typing.Annotated 的写法),仓库同时提供不使用 Annotated 的等价版本 docs_src/cookie_params/tutorial001_py310.py

声明 Cookie 参数

导入完成后,你就可以采用与 PathQuery 完全相同的结构来声明 Cookie 参数。

方式一:Annotated 写法(推荐)

@app.get("/items/")
async def read_items(ads_id: Annotated[str | None, Cookie()] = None):
    return {"ads_id": ads_id}

方式二:默认值写法

from fastapi import Cookie, FastAPI

app = FastAPI()


@app.get("/items/")
async def read_items(ads_id: str | None = Cookie(default=None)):
    return {"ads_id": ads_id}

在上面的示例中,我们声明了一个可选的 Cookie 参数 ads_id,其类型为 str | None,默认值为 None。当客户端请求 /items/ 并携带 Cookie: ads_id=xxx 时,函数就能拿到这个值;未携带时则得到 None,不会触发 422 校验错误。

在声明中加入默认值与校验

Cookie 参数同样支持「默认值 + 全部额外的校验与注解参数」的组合。例如:

from typing import Annotated
from fastapi import Cookie, FastAPI

app = FastAPI()


@app.get("/items/")
async def read_items(
    session_id: Annotated[
        str,
        Cookie(
            default=None,
            max_length=64,
            description="客户端会话标识",
            alias="session_id",
        ),
    ] = None,
):
    return {"session_id": session_id}

从上文 fastapi/param_functions.py 中的函数签名可以看到,Cookie() 支持非常完整的参数集合,其中包括:

参数 作用
default 参数未设置时的默认值
default_factory 用于生成默认值的可调用对象
alias / validation_alias / serialization_alias 为参数指定别名(可用于 Python 保留字等无法直接用作变量名的场景),影响取值与 OpenAPI 生成
title / description 参数的展示标题与说明,会进入 OpenAPI schema
gt / ge / lt / le 数值范围校验(大于 / 大于等于 / 小于 / 小于等于)
min_length / max_length 字符串长度下限 / 上限
pattern 字符串正则校验(regex 已弃用,请改用 pattern
strict 是否启用严格模式(关闭隐式类型转换)
multiple_of / max_digits / decimal_places 面向数值的额外校验(倍数、最大位数、小数位数)
deprecated 在 OpenAPI 文档中标记该参数已弃用
include_in_schema 是否把该参数包含进 OpenAPI schema
json_schema_extra 向 JSON Schema 注入额外字段
examples / openapi_examples 为参数补充文档示例(example 已随 OpenAPI 3.1 弃用)

从类定义来看,上述能力并非 Cookie 独有——见 fastapi/params.pyclass Cookie(Param) 只是把 in_ 设置为 ParamTypes.cookie,再原样把全套字段校验参数透传给父类 Param。因此 Cookie 参数能够获得与 QueryPath 一致的开箱即用的数据校验、序列化与文档生成体验。

技术细节:CookiePathQuery 的姊妹关系

官方文档特别强调了一个技术细节:CookiePathQuery 的「姊妹类(sister class)」,它们共同继承自同一个 Param 基类。

但还有一个更隐蔽的知识点值得注意:当你 from fastapi import Cookie, Path, Query 时,导入的这几个名字实际上是函数,这些函数会返回真正参与参数解析的特殊类实例。以仓库源码为例,fastapi/param_functions.py 中定义的是 def Cookie(...),其函数体最终在 fastapi/param_functions.py 处执行 return params.Cookie(...);而真正的类定义 class Cookie(Param) 位于 fastapi/params.py,它通过 in_ = ParamTypes.cookie 来标记自己属于「Cookie 来源」的参数。

这条调用链在依赖求解阶段如何被消费?在 fastapi/dependencies/utils.pyadd_param_to_fields() 中,FastAPI 依据 field_info.in_ 的值进行分派:ParamTypes.path 归入 path_paramsParamTypes.query 归入 query_paramsParamTypes.header 归入 header_params,其余情况下断言其必须为 ParamTypes.cookie 并归入 dependant.cookie_params。这正是「Cookie 参数走独立解析通道、不会与查询参数混淆」的实现基础。

重要提醒:必须用 Cookie,否则会被当作查询参数

一个新手极易踩坑的规则是:要声明 Cookie,必须使用 Cookie()

原因在于,FastAPI 对普通函数参数有一套默认推断逻辑——当一个参数没有用 PathQueryCookieHeaderBody 等显式声明,且又不属于路径模板中的变量时,它默认会被解释成查询参数 Query。所以如果你写:

async def read_items(ads_id: str | None = None):  # ❌ 会被当作查询参数
    ...

FastAPI 会认为 ads_id 是一个可选的 query 参数,而不是从请求 Cookie 中读取。只有显式标注 Cookie()Annotated[..., Cookie()],取值来源才会被修正为 Cookie。

浏览器、JavaScript 与 Cookie:Swagger UI 里的特殊情况

Cookie 由浏览器在幕后以特殊方式管理,普通网页中的 JavaScript 并不能轻易直接读取或设置它们(这与 URL 查询参数完全不同)。

这一点直接影响了你在 /docs(Swagger UI)中的调试体验:

  • 在 API 文档 UI 中,你确实可以看到每个 path operation 的 Cookie 参数文档说明——FastAPI 会根据声明自动把 ads_id 这类参数渲染到 OpenAPI 页面中,其位置标记为 in: cookie
  • 但是,即使你在 UI 里填写了数据并点击 "Execute",由于该文档 UI 本身是用 JavaScript 运行的,请求发出时并不会携带你填写的 Cookie
  • 最终你会看到一个形如「好像根本没填任何值」的 error 提示(例如缺少必填 Cookie 值时的 422 校验错误)。

这不是代码 bug,而是浏览器安全模型 + UI 运行机制共同决定的预期行为。想真正调试带 Cookie 的接口,请使用支持设置 Cookie 的 HTTP 客户端(如 curl 的 -b "ads_id=xxx"、Postman 或 FastAPI 自带的 TestClient)。

用仓库测试验证完整行为

仓库为教程配套了完整的测试,见 tests/test_tutorial/test_cookie_params/test_tutorial001.py。该测试覆盖了四种典型场景:

("/items", None, 200, {"ads_id": None}),                        # 无任何 Cookie
("/items", {"ads_id": "ads_track"}, 200, {"ads_id": "ads_track"}),  # 命中目标 Cookie
("/items", {"ads_id": "ads_track", "session": "cookiesession"}, 200, {"ads_id": "ads_track"}),  # 忽略无关 Cookie
("/items", {"session": "cookiesession"}, 200, {"ads_id": None}),  # 只传无关 Cookie

它通过 TestClient(app, cookies=cookies) 注入请求 Cookie,验证了:目标 Cookie 能被正确提取、无关 Cookie 会被安全忽略、缺省时返回默认值 None 且状态码保持 200。测试还额外断言了 /openapi.json 中生成的参数定义,其中关键字段为:

{
  "name": "ads_id",
  "in": "cookie",
  "required": false,
  "schema": {"anyOf": [{"type": "string"}, {"type": "null"}]}
}

注意这里的 "in": "cookie"——它直观地证实了 Cookie 参数会被正确路由到 OpenAPI 的 cookie 位置,而非 queryheader,与源码中 in_ = ParamTypes.cookie 的分类结果完全一致。

小结:与 Query / Path 保持一致的心智模型

回顾全文,Cookie 参数的声明并不需要新的学习成本,只需沿用 QueryPath 的同一套通用模式:

  1. fastapi 导入 Cookie(它实际是返回 params.Cookie 特殊类实例的函数);
  2. 在函数签名中用 Cookie() 标注参数,必要时借助 Annotated 组合类型与默认值;
  3. 可选地叠加 max_lengthpatternaliasdescriptiondeprecated 等校验与文档参数;
  4. 记住「不加 Cookie 就会被当作 query 参数」,以及「Swagger UI 无法真正发送 Cookie,需用专业客户端调试」。

如需继续深入,可对比阅读同目录下的 查询参数教程路径参数教程,你会发现 Cookie、Header、Query、Path 在 FastAPI 中遵循完全统一的设计哲学。

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

项目优选

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