写接口之前,有四个概念你绕不开:CORS(跨域访问的边界)、Cookie(浏览器里的「会员卡」)、Session(服务器端的「存包柜」)、JWT(带签名的「通行证」)。它们管的都是同一件事——「你是谁、你能访问什么、我凭什么信你」。本章用费曼方式(先讲生活类比,再讲代码)把它们一次讲透。
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app, resources={r"/api/*": {"origins": ["http://localhost:5173", "http://localhost:5000"]}})
这样,前端只要从 5173 或 5000 发 /api/* 请求,响应头里就会带上 Access-Control-Allow-Origin: http://localhost:5173,浏览器就放行。from flask import make_response
@app.route("/set")
def set_cookie():
resp = make_response({"msg": "已发卡"})
# key, value, max_age 秒
resp.set_cookie("user_id", "9527", max_age=3600, httponly=True)
return resp
浏览器收到响应后,会自动把 user_id=9527 存起来。以后每次请求同一域名,请求头里都会自动带上 Cookie: user_id=9527,Flask 里用 request.cookies.get("user_id") 就能读到。from flask import Flask, session
app = Flask(__name__)
app.secret_key = "你的随机密钥" # 用于给 session cookie 签名
@app.route("/login")
def login():
session["user_id"] = 9527
return {"msg": "已存柜"}
@app.route("/me")
def me():
return {"user_id": session.get("user_id")}
这里 Flask 实际做了两件事:① 在浏览器 Cookie 里放一个加密的 session_id;② 默认把 Session 数据也编码进 Cookie(Flask 客户端 session),服务端不额外存。如果换成 RedisSession 插件,数据才真正存在服务器端的 Redis 里。import jwt, datetime
from flask import request
SECRET = "你的长随机密钥"
# 登录成功后签发 token
def make_token(user_id):
payload = {
"user_id": user_id,
"exp": datetime.datetime.utcnow() + datetime.timedelta(hours=24)
}
return jwt.encode(payload, SECRET, algorithm="HS256")
# 每次请求时校验
def verify_token():
token = request.headers.get("Authorization", "").replace("Bearer ", "")
try:
return jwt.decode(token, SECRET, algorithms=["HS256"])
except jwt.ExpiredSignatureError:
return None # 票过期了
except jwt.InvalidTokenError:
return None # 假票
前端拿到 token 后,每次发请求都在请求头里带上 Authorization: Bearer <token>。Flask 验签即可,不用查数据库。| 概念 | 一句话 | 数据存在哪 | 适合场景 |
|---|---|---|---|
| CORS | 后端告诉浏览器:「这个前端域名可以读我」 | 响应头里 | 前后端分离、不同端口/域名 |
| Cookie | 服务器发的小纸条,浏览器以后每次请求自动带上 | 浏览器 | 保存无意义标识、记住登录偏好 |
| Session | 服务器用 Cookie 里的柜号,打开属于你的「存包柜」 | 服务器(内存/Redis/DB) | 需要服务器记住状态、可即时失效 |
| JWT | 服务器签发带签名的通行证,你自己拿着走 | 客户端 | 前后端分离、微服务、移动端、无状态集群 |
第 1 题:两个小区隔着一条马路。A 小区的访客想进 B 小区拿快递,B 小区的保安说:「我只让名单上的人进。」于是 B 小区物业把访客的车牌号登记到放行名单里,保安看到车牌就让进。CORS 就是这个放行名单。
第 2 题:Session 给每个用户一个「柜号」,服务器用柜号找到属于他的数据,所以在多次请求之间能记住用户。浏览器禁用 Cookie 后,柜号无法带回,服务器找不到柜子,Session 就失效了。
第 3 题:JWT 的优势是服务器不存会话,任何一台机器都能验签;劣势是 token 无法中途作废,只能等过期。降低损失的做法:① token 有效期设短(如 2 小时);② 用 Refresh Token + Access Token 双 token;③ 敏感接口(改密码、转账)必须要求重新输入密码或短信验证。