官方文档:Cookie 参数 - FastAPI

定义 Cookie 参数与定义 Query 和 Path 参数一样。

源码:

from typing import Annotated

from fastapi import Cookie, FastAPI

app = FastAPI()


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

首先,导入 Cookie

from fastapi import Cookie, FastAPI

声明 Cookie 参数的方式与声明 Query 和 Path 参数相同。第一个值是默认值,还可以传递所有验证参数或注释参数:

async def read_items(ads_id: Annotated[str | None, Cookie()] = None):

"技术细节"

Cookie 、Path 、Query 是兄弟类,都继承自共用的 Param 类。

注意,从 fastapi 导入的 QueryPathCookie 等对象,实际上是返回特殊类的函数。

"说明"

必须使用 Cookie 声明 cookie 参数,否则该参数会被解释为查询参数。

小结

使用 Cookie 声明 cookie 参数的方式与 Query 和 Path 相同。

Cookie参数模型



如果你有一组相关的Cookie,你可以创建一个Pydantic模型来声明它们。🍪
这将允许您在多个地方重用模型,并一次声明所有参数的验证和元数据。😎

注:
自FastAPI 0.115.0版本起支持此功能。🤓

小贴士
同样的技术也适用于Query、Cookie和Header。😎


具有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

查看文档


您可以在/docs的文档UI中看到已定义的Cookie:


资讯
请记住,由于浏览器在幕后以特殊方式处理Cookie,因此它们不容易让JavaScript接触到它们。
如果您访问/docs上的API docs UI,您将能够看到路径操作的Cookie文档。
但是,即使您填写数据并单击“执行”,由于文档UI使用JavaScript,Cookie也不会被发送,您将看到一条错误消息,就像您没有写入任何值一样。


禁止额外Cookie


在某些特殊情况下(可能不是很常见),您可能希望限制您想要接收的Cookie。
您的API现在有权控制自己的cookie同意。🤪🍪
您可以使用Pydantic的模型配置来禁止任何额外的字段:

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

如果客户端尝试发送一些额外的Cookie,他们将收到错误响应。
可怜的cookie横幅,他们竭尽全力让API同意拒绝它。🍪
例如,如果客户端尝试发送一个值为good-list please的santa_tracker cookie,客户端将收到一个错误响应,告诉他们不允许使用santa_track cookie:

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

摘要


您可以使用Pydantic模型在FastAPI中声明Cookie。😎

实践

又碰到问题了,这里是获得cookie,那么应该怎么来实践检验一下呢? 我认为需要先想办法把cookie存进去才行。

在测试中用浏览器发送cookie进去有点麻烦,需要按F12然后进行一些操作,那么问题就变成:

应该怎么用curl来发送带有cookie的请求?

后来发现curl可以用-b参数带cookie,如:

curl -X GET "http://127.0.0.1:8000/items/" -b "ads_id=12345" -b "another_cookie=67890"

curl -X GET "http://127.0.0.1:8000/items/" -b "session_id=abc123;fatebook_tracker=fb_track_123;googall_tracker=ga_track_456"

FastAPI cookie源码

将代码存为cookie.py文件

from typing import Annotated

from fastapi import Cookie, FastAPI
from pydantic import BaseModel

app = FastAPI()


class Cookies(BaseModel):
    # 禁止其它cookie
    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

启动服务

uvicorn cookie:app --reload

curl 进行cookie测试

执行curl命令和输出:

curl -X GET "http://127.0.0.1:8000/items/" -b "session_id=abc123;fatebook_tracker=fb_track_123;googall_tracker=ga_track_456"
{"session_id":"abc123","fatebook_tracker":"fb_track_123","googall_tracker":"ga_track_456"}

测试通过!

 

禁止额外cookie

代码写入cookie.py文件:

from typing import Annotated

from fastapi import Cookie, FastAPI
from pydantic import BaseModel

app = FastAPI()


class Cookies(BaseModel):
    # 禁止其它cookie
    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

 启动服务

uvicorn cookie:app --reload

curl 进行cookie测试

 

如果有超过设置的cookie,会报错

curl -X GET "htt.0.1:8000/items/" -b "session_id=abc123;test=test;fatebook_tracker=fb_track_123;googall_tracker=ga_track_456;temp=test"
{"detail":[{"type":"extra_forbidden","loc":["cookie","test"],"msg":"Extra inputs are not permitted","input":"test"},{"type":"extra_forbidden","loc":["cookie","temp"],"msg":"Extra inputs are not permitted","input":"test"}]}

如果直接用chromium浏览器浏览:http://127.0.0.1:8000/items/

因为浏览器会自动放一些cookie,所以也会报错:

{"detail":[{"type":"missing","loc":["cookie","session_id"],"msg":"Field required","input":{"CSRF-Token-5QWX4YR":"qThiWAbkWwNwXTA624FM3XUWZYkCujme","sessionid-5QWX4YR":"rhumGzAQQv9SmQobMdYcQKZgNpNFMgnK"}},{"type":"extra_forbidden","loc":["cookie","CSRF-Token-5QWX4YR"],"msg":"Extra inputs are not permitted","input":"qThiWAbkWwNwXTA624FM3XUWZYkCujme"},{"type":"extra_forbidden","loc":["cookie","sessionid-5QWX4YR"],"msg":"Extra inputs are not permitted","input":"rhumGzAQQv9SmQobMdYcQKZgNpNFMgnK"}]}

 

总结

 使用 Cookie 声明 cookie 参数的方式与 Query 和 Path 相同,写起来毫无压力!

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐