跳到内容

Cookie 参数模型

如果你有一组相关的 cookie,你可以创建一个 Pydantic 模型来声明它们。🍪

这样你就可以在多个地方重用该模型,并且可以一次性声明所有参数的验证和元数据。😎

注意

FastAPI 0.115.0 版本开始支持此功能。🤓

提示

同样的技术也适用于 QueryCookieHeader。😎

使用 Pydantic 模型处理 Cookie

Pydantic 模型中声明你需要的 cookie 参数,然后将该参数声明为 Cookie

from typing import Annotated

from fastapi import Cookie, FastAPI
from pydantic import BaseModel

app = FastAPI()


class Cookies(BaseModel):
    session_id: str
    fatebook_tracker: str | None = None
    googall_tracker: str | None = None


@app.get("/items/")
async def read_items(cookies: Annotated[Cookies, Cookie()]):
    return cookies
🤓 其他版本和变体
from typing import Annotated, Union

from fastapi import Cookie, FastAPI
from pydantic import BaseModel

app = FastAPI()


class Cookies(BaseModel):
    session_id: str
    fatebook_tracker: Union[str, None] = None
    googall_tracker: Union[str, None] = None


@app.get("/items/")
async def read_items(cookies: Annotated[Cookies, Cookie()]):
    return cookies
from typing import Union

from fastapi import Cookie, FastAPI
from pydantic import BaseModel
from typing_extensions import Annotated

app = FastAPI()


class Cookies(BaseModel):
    session_id: str
    fatebook_tracker: Union[str, None] = None
    googall_tracker: Union[str, None] = None


@app.get("/items/")
async def read_items(cookies: Annotated[Cookies, Cookie()]):
    return cookies

提示

如果可能,请优先使用 Annotated 版本。

from fastapi import Cookie, FastAPI
from pydantic import BaseModel

app = FastAPI()


class Cookies(BaseModel):
    session_id: str
    fatebook_tracker: str | None = None
    googall_tracker: str | None = None


@app.get("/items/")
async def read_items(cookies: Cookies = Cookie()):
    return cookies

提示

如果可能,请优先使用 Annotated 版本。

from typing import Union

from fastapi import Cookie, FastAPI
from pydantic import BaseModel

app = FastAPI()


class Cookies(BaseModel):
    session_id: str
    fatebook_tracker: Union[str, None] = None
    googall_tracker: Union[str, None] = None


@app.get("/items/")
async def read_items(cookies: Cookies = Cookie()):
    return cookies

FastAPI 将从请求中收到的 cookie 中为每个字段 提取数据,并为你提供你定义的 Pydantic 模型。

查看文档

你可以在 /docs 的文档 UI 中看到已定义的 cookie。

信息

请注意,由于浏览器以特殊的方式在后台处理 cookie,它们轻易允许 JavaScript 接触它们。

如果你访问 /docsAPI 文档 UI,你将能看到你的路径操作cookie 文档

但即使你填写了数据并点击“执行”,因为文档 UI 是通过 JavaScript 工作的,cookie 也不会被发送,你会看到一个错误消息,就好像你没有填写任何值一样。

禁止额外的 Cookie

在一些特殊的(可能不是很常见的)用例中,你可能想要限制你希望接收的 cookie。

你的 API 现在有权控制自己的 cookie 同意了。🤪🍪

你可以使用 Pydantic 的模型配置来 forbid 任何 extra 字段

from typing import Annotated, Union

from fastapi import Cookie, FastAPI
from pydantic import BaseModel

app = FastAPI()


class Cookies(BaseModel):
    model_config = {"extra": "forbid"}

    session_id: str
    fatebook_tracker: Union[str, None] = None
    googall_tracker: Union[str, None] = None


@app.get("/items/")
async def read_items(cookies: Annotated[Cookies, Cookie()]):
    return cookies
🤓 其他版本和变体
from typing import Annotated

from fastapi import Cookie, FastAPI
from pydantic import BaseModel

app = FastAPI()


class Cookies(BaseModel):
    model_config = {"extra": "forbid"}

    session_id: str
    fatebook_tracker: str | None = None
    googall_tracker: str | None = None


@app.get("/items/")
async def read_items(cookies: Annotated[Cookies, Cookie()]):
    return cookies
from typing import Union

from fastapi import Cookie, FastAPI
from pydantic import BaseModel
from typing_extensions import Annotated

app = FastAPI()


class Cookies(BaseModel):
    model_config = {"extra": "forbid"}

    session_id: str
    fatebook_tracker: Union[str, None] = None
    googall_tracker: Union[str, None] = None


@app.get("/items/")
async def read_items(cookies: Annotated[Cookies, Cookie()]):
    return cookies

提示

如果可能,请优先使用 Annotated 版本。

from fastapi import Cookie, FastAPI
from pydantic import BaseModel

app = FastAPI()


class Cookies(BaseModel):
    model_config = {"extra": "forbid"}

    session_id: str
    fatebook_tracker: str | None = None
    googall_tracker: str | None = None


@app.get("/items/")
async def read_items(cookies: Cookies = Cookie()):
    return cookies

提示

如果可能,请优先使用 Annotated 版本。

from typing import Union

from fastapi import Cookie, FastAPI
from pydantic import BaseModel

app = FastAPI()


class Cookies(BaseModel):
    model_config = {"extra": "forbid"}

    session_id: str
    fatebook_tracker: Union[str, None] = None
    googall_tracker: Union[str, None] = None


@app.get("/items/")
async def read_items(cookies: Cookies = Cookie()):
    return cookies

如果客户端试图发送一些额外的 cookie,他们将收到一个错误响应。

可怜的 cookie 横幅费尽心机获取你的同意,结果却被 API 拒绝了。🍪

例如,如果客户端尝试发送一个值为 good-list-pleasesanta_tracker cookie,客户端将收到一个错误响应,告诉他们 santa_tracker cookie 是不允许的

{
    "detail": [
        {
            "type": "extra_forbidden",
            "loc": ["cookie", "santa_tracker"],
            "msg": "Extra inputs are not permitted",
            "input": "good-list-please",
        }
    ]
}

总结

你可以使用 Pydantic 模型FastAPI 中声明 cookie。😎