当前位置: 首页 > news >正文

FastAPI 请求头与 Cookie:Web 世界的“身份证”与“通行证”

你每天上网的时候,有没有好奇过一个问题:

为什么你登录淘宝之后,不管点进“购物车”、“订单详情”还是“个人中心”,网站都知道你是谁?

答案并不是你每次点击都把用户名和密码重新发一遍(那样太危险了),而是你的浏览器在每一次请求的背后,悄悄携带了两样东西:请求头(Headers) 和 Cookie。

就像你进小区要刷门禁卡,进公司要刷工牌一样,请求头和 Cookie 就是 Web 世界里辨别你身份的“电子证件”。它们虽然看不见摸不着,但每一次的页面跳转、每一次的 API 调用,都在默默地发挥着作用。

本文将站在普通 Web 用户的视角,深入浅出地讲清楚请求头和 Cookie 到底是什么、有什么区别,以及 FastAPI 如何轻松读取它们,让你的后端服务具备识别用户、控制访问的能力。

一、什么是请求头?(快递包裹的面单)
想象一下,你收到一个快递。

快递盒里装着你买的手机(这是请求体 Body),快递面单上写着你的地址(这是路径参数),面单角落还有备注“轻拿轻放”(这是查询参数)。

但除了这些,快递盒上还有很多你看不到、但对于快递公司至关重要的信息:

寄件人信息(谁发的?)

快递单号(追踪用)

承运方式(空运还是陆运?)

包裹重量(计费依据)

面单版本号(系统识别用)

这些信息,就是 HTTP 请求中的 请求头(Headers)。

请求头是 HTTP 请求的“元数据(Metadata)”,即“描述数据的数据”。它不承载业务的核心内容(那是 Body 的活),而是告诉服务器:“我是谁”、“我从哪里来”、“我能接受什么”、“我的连接状态如何”。

在浏览器的开发者工具中(F12 → Network),你可以看到每一个请求都有密密麻麻的

Headers:

GET /api/profile HTTP/1.1 Host: example.com User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Accept: application/json Accept-Language: zh-CN,zh;q=0.9 Authorization: Bearer eyJhbGciOiJIUzI1NiIs... Cookie: session_id=abc123; theme=dark

这些键值对,就是请求头。

二、什么是 Cookie?(商场的会员卡)
Cookie 本质上只是请求头里的一行特殊字段(Cookie: key=value),但它的地位太重要了,值得单独拎出来讲。

想象你去一家大型商场。

如果你每次买东西都要出示身份证(输入用户名密码),太麻烦。

于是商场给你办了一张会员卡(Cookie)。

卡上写着你的会员编号(用户 ID),商场系统通过这张卡识别你是老顾客。

每次你结账时,收银员扫一下卡(浏览器自动携带 Cookie),就知道你是谁、有没有折扣、积分多少。

但会员卡有有效期(过期时间),过期了需要重新激活(重新登录)。

Cookie 的本质,就是服务器颁发给浏览器的一小段文本信息(通常不超过 4KB),浏览器将其保存在本地,并在之后的每一次请求中自动携带回服务器。它主要用于保持会话状态(Session),让无状态的 HTTP 协议“记住”你是谁。

三、请求头 vs Cookie:一张表看懂区别

四、FastAPI 如何读取请求头?
在 FastAPI 中,读取请求头就像读取普通的函数参数一样简单。

1. 基础用法:使用 Header

from fastapi import FastAPI, Header app = FastAPI() @app.get("/user-agent/") async def get_user_agent(user_agent: str = Header(None)): return {"user_agent": user_agent}

请求:GET /user-agent/,浏览器会自动携带 User-Agent 头。后端直接拿到字符串,比如 "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"。

注意:Header 默认会把参数名转为小写加下划线的形式(user_agent → User-Agent),非常贴心。

2. 读取自定义请求头
前端或客户端可以发送自定义请求头(通常以 X- 开头):

@app.get("/custom-header/") async def custom_header( x_request_id: str = Header(None, description="自定义请求追踪ID"), x_api_version: str = Header("v1") ): return {"request_id": x_request_id, "api_version": x_api_version}

前端请求时带上 X-Request-ID: req-2026-001,后端就能拿到这个值用于日志追踪。

3. 使用 Depends 封装 Header 解析
如果多个接口都需要解析某个请求头(比如 Authorization),可以封装成依赖项复用:

from fastapi import Depends, HTTPException async def get_token(authorization: str = Header(...)): if not authorization.startswith("Bearer "): raise HTTPException(401, "Invalid token format") return authorization.split(" ")[1] @app.get("/secure-data/") async def secure_data(token: str = Depends(get_token)): return {"token": token, "data": "这是敏感数据"}

五、FastAPI 如何读取 Cookie?
1. 基础用法:使用 Cookie
FastAPI 提供了 Cookie 函数,用于从请求中提取 Cookie 值:

from fastapi import FastAPI, Cookie app = FastAPI() @app.get("/profile/") async def get_profile(session_id: str = Cookie(None)): if not session_id: return {"error": "未登录"} return {"message": f"欢迎回来,你的 session 是 {session_id}"}

浏览器访问 /profile/ 时,会自动携带该域名下的所有 Cookie。Cookie("session_id") 就是从 Cookie: session_id=abc123 中提取 abc123。

2. 设置 Cookie(服务器响应)
除了读 Cookie,服务器还需要给客户端“发”Cookie。这需要使用 Response 对象:

from fastapi import FastAPI, Response app = FastAPI() @app.post("/login/") async def login(response: Response, username: str): # 假设验证成功,给浏览器发一个 Cookie response.set_cookie( key="session_id", value="abc123xyz", max_age=3600, # 1小时后过期 httponly=True, # 禁止 JavaScript 读取(防 XSS) secure=True, # 仅 HTTPS 传输 samesite="lax" # 防 CSRF 攻击 ) return {"message": f"{username} 登录成功"}

浏览器收到响应后,会把 session_id=abc123xyz 存到本地。下次再访问同域名下的任何页面,浏览器会自动在请求头里带上 Cookie: session_id=abc123xyz,服务器就知道你是谁了。

六、请求头的五大核心作用(站在用户视角)
1. 身份认证(你是谁?)
最常见的用途。用户登录后,服务器返回一个 Token(JWT),前端在后续请求中通过 Authorization: Bearer <token> 头发送给服务器。这就是现代 Web 中最主流的无状态认证方式。

用户感知:你登录过一次之后,接下来几天打开 App 都不用重新输密码。

2. 内容协商(你想要什么格式?)
浏览器通过 Accept 头告诉服务器它能接受什么格式的数据。

Accept: application/json → 请返回 JSON

Accept: text/html → 请返回 HTML

Accept-Language: zh-CN → 请返回中文内容

这就是为什么同一个 API 地址,浏览器访问返回 HTML 页面,移动端访问返回 JSON 数据。

用户感知:你的浏览器自动请求中文页面,而你在国外时自动显示英文,无需手动切换。

3. 缓存控制(快不快?)
Cache-Control 头告诉服务器和浏览器如何缓存资源,直接影响你的网页加载速度。

用户感知:刷新微博首页时,LOGO 图片几乎是瞬间加载的,因为它被浏览器缓存了。

4. 安全防护(安不安全?)
Referer:告诉服务器你是从哪个页面跳转过来的,用于防盗链。

User-Agent:告诉服务器你用的什么浏览器,用于适配不同的渲染策略。

Origin:用于 CORS(跨域资源共享),控制哪些网站能调用你的 API。

用户感知:你在 A 网站点击链接跳转到 B 网站,B 网站知道你是从 A 来的,可能给你展示不同的欢迎语。

5. 追踪与调试(出问题了找谁?)
企业级应用中,请求头常用于链路追踪。每个请求携带一个唯一的 X-Request-ID,贯穿整个微服务调用链。

用户感知:当你在 App 上报 Bug 时,客服让你提供“请求编号”,就是这个 ID 帮助你快速定位问题。

七、Cookie 的三大核心作用(站在用户视角)
1. 会话管理(保持登录态)
这是 Cookie 最经典的应用。用户登录后,服务器下发一个包含用户 ID 的加密 Cookie,浏览器保存。后续每次请求都带着它,服务器就知道你是谁,无需重复登录。

用户感知:你登录淘宝后,关掉浏览器再打开,发现还是登录状态(只要没点“退出登录”)。

2. 用户偏好追踪
网站通过 Cookie 记住你的个性化设置。

用户感知:你把网站主题改成“深色模式”,下次打开还是深色模式;你在购物车加的商品,隔天还在。

3. 流量分析与个性化推荐
第三方追踪 Cookie(如 Google Analytics)记录你的浏览行为,用于分析流量和推送广告。

用户感知:你搜过“旅行箱”后,接下来几天到处都能看到旅行箱广告——这就是追踪 Cookie 的“功劳”。

八、最佳实践与安全指南
1. 敏感信息不要放在 Cookie 里
Cookie 虽然方便,但不要明文存储密码、信用卡号等极敏感信息。应该存一个无意义的 Session ID,真正的用户数据放在服务端数据库中。

2. 给 Cookie 加三道安全锁

response.set_cookie( key="session_id", value="abc123", httponly=True, # 🔒 防 XSS:JS 读不到,只能浏览器发送 secure=True, # 🔒 防窃听:仅 HTTPS 传输 samesite="lax" # 🔒 防 CSRF:跨站请求不携带 )

这三道锁是现代 Web 安全的基本防线。

3. 使用 Token(JWT)替代 Cookie 做认证
在纯 API 服务(前后端分离)中,Cookie 依赖浏览器机制,移动端并不适用。更推荐在请求头中使用 Authorization: Bearer <JWT> 做认证,它是跨平台的。

4. 区分“请求头解析失败”与“未登录”
请求头解析失败返回 422(参数错误),认证失败返回 401(未授权),权限不足返回 403(禁止)。语义要清晰,不要混用。

@app.get("/admin") async def admin_panel(authorization: str = Header(None)): if not authorization: raise HTTPException(401, "请先登录") if authorization != "Bearer secret_admin_token": raise HTTPException(403, "权限不足,需要管理员权限") return {"message": "欢迎管理员"}

5. 不要依赖 Referer 做唯一安全验证
Referer 头可以被浏览器策略或用户设置禁用,也可能被伪造。只把它作为辅助参考,不要作为唯一的安全防线。

九、结语
对于普通 Web 用户而言,请求头和 Cookie 就是你和互联网服务之间那层看不见的“默契”:

每次打开网页,浏览器都在背后默默递上你的“电子身份证”(请求头)。

每次点击“保持登录”,浏览器都在本地存下你的“会员卡”(Cookie)。

它们像空气一样无处不在,却默默承载着认证、追踪、安全、缓存、内容协商等无数关键功能,让你每一次点击都能得到个性化的、安全的、快速的响应。

对于 FastAPI 开发者而言,Header 和 Cookie 是框架提供的两把轻量级钥匙。你无需手动解析原始请求字符串,只需在路由函数参数中声明你要读取的字段,框架就会自动提取、自动注入,让你用最少的代码,构建出最安全的身份识别系统。

http://www.jsqmd.com/news/1138293/

相关文章:

  • 如何快速配置Qwen图像编辑模型:面向AI创作者的完整指南
  • clickhouse24.9.2.42单机版linux安装
  • AI时代,如何从“写代码”小白变身大模型高手?收藏这份程序员转型指南
  • 城市生命线智慧管网建设落地指南|北京益豪时代一站式解决地下管网安全管控难题
  • 从拆解到设计:基于ME4057与CN5711的5V/1A充电宝LED灯PCB布局3要点
  • 基于 STM32 的实验室药品自动存取与库存管理系统设计
  • AI视觉落地实战:GlowUp AI 全场景个人形象定制技术解析与场景测评
  • 帮正在填志愿的学生和家长,想清楚“要不要学计算机、怎么选专业、报哪所大学” 这三件事。它不是标准答案,而是一份有态度的参考。
  • 2026揭阳财税公司哪家专业,本土全品类电商 TOP实力深度解析
  • 3 种点云补全网络对比:PF-Net vs PCN vs TopNet,在 ShapeNet 上的 F-Score 评测
  • 153、LangChain Chain:LLMChain、SequentialChain、RouterChain 的链式编排
  • Alpha Go的前世今生
  • F. A Bit Odd-从零开始的博弈题解 [特殊字符](Codeforces 2241)
  • 3步快速上手res-downloader:终极视频解密下载工具完整指南
  • A-Lin黄丽玲宁波连唱三晚 携金曲奖作品《幸福在歌唱》点燃巡演热情
  • Seedance 2.0 API 实战:多模态视频生成与工程落地
  • COMSOL 6.2 有限元仿真:平行板电容器边缘效应分析,电容误差仅 2.7%
  • FastAPI 请求体:Web 表单背后的“数据包裹”
  • PCIe-2.2.4 Routing and Addressing Rules(address ID)
  • VRM 四元件模型仿真实战:4个参数对电源阻抗影响的量化分析
  • 【HarmonyOS】View点击穿透,层叠View点击事件控制
  • 【薅羊毛】紧急扩散!免费2核4G云服务器新羊毛,不关机不限时,一个账号2台,手慢无!
  • 2026年找市面上不踩坑的手工辣条厂家 这些挑选技巧快收好
  • 这里是九年义务漏网鲨鱼
  • exe 文件探测开发语言检测-软件分析—东方仙盟
  • 上位机学习第四天
  • AI写专著神器来袭!一键生成20万字专著,低查重率有保障!
  • 上海世邦MTW欧版磨打造山西工业固废高值化新方案
  • Python爬虫经典案例第86篇:在线代码托管平台爬取:Gitee数据采集实战
  • GitHub嵌入式项目深度推荐:从实战到前沿