
你每天上网的时候有没有好奇过一个问题为什么你登录淘宝之后不管点进“购物车”、“订单详情”还是“个人中心”网站都知道你是谁答案并不是你每次点击都把用户名和密码重新发一遍那样太危险了而是你的浏览器在每一次请求的背后悄悄携带了两样东西请求头Headers 和 Cookie。就像你进小区要刷门禁卡进公司要刷工牌一样请求头和 Cookie 就是 Web 世界里辨别你身份的“电子证件”。它们虽然看不见摸不着但每一次的页面跳转、每一次的 API 调用都在默默地发挥着作用。本文将站在普通 Web 用户的视角深入浅出地讲清楚请求头和 Cookie 到底是什么、有什么区别以及 FastAPI 如何轻松读取它们让你的后端服务具备识别用户、控制访问的能力。一、什么是请求头快递包裹的面单想象一下你收到一个快递。快递盒里装着你买的手机这是请求体 Body快递面单上写着你的地址这是路径参数面单角落还有备注“轻拿轻放”这是查询参数。但除了这些快递盒上还有很多你看不到、但对于快递公司至关重要的信息寄件人信息谁发的快递单号追踪用承运方式空运还是陆运包裹重量计费依据面单版本号系统识别用这些信息就是 HTTP 请求中的 请求头Headers。请求头是 HTTP 请求的“元数据Metadata”即“描述数据的数据”。它不承载业务的核心内容那是 Body 的活而是告诉服务器“我是谁”、“我从哪里来”、“我能接受什么”、“我的连接状态如何”。在浏览器的开发者工具中F12 → Network你可以看到每一个请求都有密密麻麻的HeadersGET /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;q0.9 Authorization: Bearer eyJhbGciOiJIUzI1NiIs... Cookie: session_idabc123; themedark这些键值对就是请求头。二、什么是 Cookie商场的会员卡Cookie 本质上只是请求头里的一行特殊字段Cookie: keyvalue但它的地位太重要了值得单独拎出来讲。想象你去一家大型商场。如果你每次买东西都要出示身份证输入用户名密码太麻烦。于是商场给你办了一张会员卡Cookie。卡上写着你的会员编号用户 ID商场系统通过这张卡识别你是老顾客。每次你结账时收银员扫一下卡浏览器自动携带 Cookie就知道你是谁、有没有折扣、积分多少。但会员卡有有效期过期时间过期了需要重新激活重新登录。Cookie 的本质就是服务器颁发给浏览器的一小段文本信息通常不超过 4KB浏览器将其保存在本地并在之后的每一次请求中自动携带回服务器。它主要用于保持会话状态Session让无状态的 HTTP 协议“记住”你是谁。三、请求头 vs Cookie一张表看懂区别四、FastAPI 如何读取请求头在 FastAPI 中读取请求头就像读取普通的函数参数一样简单。1. 基础用法使用 Headerfrom 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 如何读取 Cookie1. 基础用法使用 CookieFastAPI 提供了 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_idabc123 中提取 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( keysession_id, valueabc123xyz, max_age3600, # 1小时后过期 httponlyTrue, # 禁止 JavaScript 读取防 XSS secureTrue, # 仅 HTTPS 传输 samesitelax # 防 CSRF 攻击 ) return {message: f{username} 登录成功}浏览器收到响应后会把 session_idabc123xyz 存到本地。下次再访问同域名下的任何页面浏览器会自动在请求头里带上 Cookie: session_idabc123xyz服务器就知道你是谁了。六、请求头的五大核心作用站在用户视角1. 身份认证你是谁最常见的用途。用户登录后服务器返回一个 TokenJWT前端在后续请求中通过 Authorization: Bearer token 头发送给服务器。这就是现代 Web 中最主流的无状态认证方式。用户感知你登录过一次之后接下来几天打开 App 都不用重新输密码。2. 内容协商你想要什么格式浏览器通过 Accept 头告诉服务器它能接受什么格式的数据。Accept: application/json → 请返回 JSONAccept: text/html → 请返回 HTMLAccept-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( keysession_id, valueabc123, httponlyTrue, # 防 XSSJS 读不到只能浏览器发送 secureTrue, # 防窃听仅 HTTPS 传输 samesitelax # 防 CSRF跨站请求不携带 )这三道锁是现代 Web 安全的基本防线。3. 使用 TokenJWT替代 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 是框架提供的两把轻量级钥匙。你无需手动解析原始请求字符串只需在路由函数参数中声明你要读取的字段框架就会自动提取、自动注入让你用最少的代码构建出最安全的身份识别系统。