FastAPI 请求头与 Cookie
FastAPI 请求头与 Cookie 学习笔记
一、请求头(Headers)
1. 基本用法 —Header
fromfastapiimportFastAPI,Header app=FastAPI()@app.get("/items/")asyncdefread_items(user_agent:str=Header(None)):return{"User-Agent":user_agent}- 使用
Header()从请求头中提取值,注入到路径操作函数的参数中。 - 默认值设为
None表示该请求头可选。
2. 自动转换规则
| HTTP 请求头写法 | Python 参数写法 | 说明 |
|---|---|---|
User-Agent | user_agent | 连字符-自动转为下划线_ |
X-Token | x_token | 参数名自动小写 |
FastAPI 内部会做以下转换:
- 连字符
-→ 下划线_:因为 Python 变量名不能包含- - 大小写不敏感:HTTP 头本身不区分大小写,Python 参数名用小写即可
3. 禁用下划线转换 —convert_underscores
如果请求头本身包含下划线(如X_API_KEY),需要禁用自动转换:
@app.get("/items/")asyncdefread_items(x_api_key:str=Header(None,convert_underscores=False)):return{"X_API_KEY":x_api_key}注意:HTTP 规范建议头名称中使用连字符而非下划线,某些代理(如 Nginx)默认会丢弃含下划线的请求头。
4. 重复请求头 —list类型
当同一请求头出现多次时,用list接收:
@app.get("/items/")asyncdefread_items(x_token:list[str]=Header(None)):return{"X-Token":x_token}# 请求: X-Token: foo X-Token: bar# 响应: {"X-Token": ["foo", "bar"]}二、Cookie
1. 基本用法 —Cookie
fromfastapiimportFastAPI,Cookie app=FastAPI()@app.get("/items/")asyncdefread_items(ads_id:str=Cookie(None)):return{"ads_id":ads_id}- 使用
Cookie()从请求的 Cookie 中提取指定名称的值。 - 参数名即为 Cookie 的 key。
2. 与 Header 的对比
| 特性 | Header() | Cookie() |
|---|---|---|
| 数据来源 | HTTP 请求头 | 请求头中的Cookie字段 |
| 名称转换 | -→_,自动小写 | 无转换,参数名即 Cookie 名 |
| 典型场景 | Token、User-Agent 等 | 会话 ID、用户偏好等 |
三、底层机制
Header、Cookie、Path、Query本质上都是Param的子类,共享相同的配置项:
Param (基类) ├── Path() — 路径参数 ├── Query() — 查询参数 ├── Header() — 请求头 ├── Cookie() — Cookie └── Body() — 请求体通用参数:
| 参数 | 说明 |
|---|---|
default | 默认值,None表示可选 |
alias | 别名,用于映射不同的名称 |
title/description | OpenAPI 文档中的标题/描述 |
gt/ge/lt/le | 数值约束(仅数值类型) |
min_length/max_length | 字符串长度约束 |
regex | 正则校验 |
四、完整示例
fromfastapiimportFastAPI,Header,Cookie app=FastAPI()@app.get("/demo/")asyncdefdemo(# 请求头user_agent:str=Header(None,description="客户端标识"),x_request_id:str=Header(None,alias="X-Request-ID"),accept:list[str]=Header(None),# Cookiesession_id:str=Cookie(None,description="会话ID"),lang:str=Cookie("zh-CN",description="语言偏好"),):return{"user_agent":user_agent,"x_request_id":x_request_id,"accept":accept,"session_id":session_id,"lang":lang,}测试请求
curl-XGET"http://127.0.0.1:8000/demo/"\-H"X-Request-ID: abc-123"\-H"Accept: application/json"\-H"Accept: text/html"\-H"Cookie: session_id=sess_xyz; lang=en-US"响应
{"user_agent":"curl/7.88.1","x_request_id":"abc-123","accept":["application/json","text/html"],"session_id":"sess_xyz","lang":"en-US"}五、注意事项
- 安全性:请求头和 Cookie 可被客户端伪造,敏感操作必须结合服务端校验(如签名、JWT 验证)。
- Nginx 下划线问题:Nginx 默认丢弃含
_的请求头,需配置underscores_in_headers on;。 - Cookie 大小限制:单个 Cookie 通常不超过 4KB,大量数据应存服务端。
- HttpOnly / Secure:设置 Cookie 时建议通过
Response对象添加安全属性:
fromfastapiimportResponse@app.post("/login")asyncdeflogin(response:Response):response.set_cookie(key="session_id",value="sess_xyz",httponly=True,# 禁止 JS 访问,防 XSSsecure=True,# 仅 HTTPS 传输samesite="lax",# 防 CSRFmax_age=3600,)return{"msg":"logged in"}- Pydantic 模型方式:也可以用
Header/Cookie配合 Pydantic 模型做批量校验,但更常见的做法是逐参数声明。
