在 Web 开发中,API 的安全性与稳定性离不开三个核心能力:认证鉴权保证“请求来自谁、能不能访问”,跨域处理解决“浏览器同源策略”的阻碍,接口限流防止服务被滥用或击垮。本节结合 Django、Flask、FastAPI 三大框架的常用方案,给出可直接落地的实践指南。
认证鉴权
目标:确认请求者身份(认证)并判断其是否有权限执行操作(鉴权)。
主流方式:
- Session-Cookie 认证(适合传统 Web 应用)
- 流程:用户登录后服务器创建 Session,把 Session ID 通过 Cookie 返回给浏览器,后续请求自动携带。
- 适用场景:前后端不分离的 Django 项目、后台管理系统。
- 实践要点:设置 Cookie 的
HttpOnly、Secure属性防止 XSS 窃取;启用 CSRF 保护;Session 可存储在 Redis 等外部缓存中,防止单点失效。
- Token 认证(适合前后端分离、移动端)
- 典型实现:JWT(JSON Web Token)。
- 流程:登录接口验证凭证后,服务器返回一个签名的 JWT;客户端在请求头
Authorization: Bearer <token>中携带;服务器验证签名、有效期即可识别用户。 - 优点:无状态,方便扩展。
- 需要注意的坑:JWT 默认不加密,切勿在 payload 中放敏感信息;Token 过期无法主动撤销,可配合 Redis 维护黑名单实现强制退出。
- OAuth2 / OIDC(第三方登录、微服务授权)
- 场景:允许用户用 GitHub、微信登录,或服务间授权。
- 方案:使用
Authlib库简化流程,或直接用云服务(如 Auth0、Firebase Auth)。Django 可用django-allauth,FastAPI 可直接集成第三方 OIDC 提供者。
- 权限控制
- 简单角色判断:自定义装饰器或中间件,检查用户的角色属性(如
user.is_admin)。 - 细粒度权限:推荐用 RBAC(基于角色的访问控制)或 ABAC。Flask 可扩展
flask-principal,Django 自带Permission和Group模型,FastAPI 可以结合依赖注入实现策略检查。
最佳实践总结:
- 密码绝不存明文,必须使用
bcrypt或passlib加密。 - 敏感操作(支付、改密)强制二次验证。
- 统一在中间件或依赖注入层处理认证,避免在各视图函数中重复编写逻辑。
跨域处理(CORS)
浏览器出于安全限制,会阻止页面请求不同源(协议、域名、端口任一不同)的 API,需要服务器明确允许。
实用方案:
- Django:使用
django-cors-headers,在settings.py中配置:
INSTALLED_APPS += ['corsheaders']
MIDDLEWARE.insert(0, 'corsheaders.middleware.CorsMiddleware')
CORS_ALLOWED_ORIGINS = ["https://yourfrontend.com"] # 生产环境指定具体域名
CORS_ALLOW_CREDENTIALS = True # 允许携带 Cookie
- Flask:推荐
flask-cors:
from flask_cors import CORS
app = Flask(__name__)
CORS(app, resources={r"/api/*": {"origins": "https://front.com"}}, supports_credentials=True)
或通过装饰器针对单个路由开启:
@app.route('/api/data')
@cross_origin(origins='*')
def data():
return jsonify({...})
- FastAPI:内置
CORSMiddleware:
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["https://front.com"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
安全原则:
- 切忌将
allow_origins设为*同时启用allow_credentials=True,浏览器违反规范会直接阻止。 - 生产环境必须指定明确的来源列表,不要图方便放行所有域。
- 只暴露需要的方法(GET、POST)和头信息,减少攻击面。
接口限流
防止单个 IP 或用户短时间内大量请求,避免服务器资源耗尽或数据被爬取。
落地工具与策略:
- Django REST Framework (DRF) 内置限流
- 配置:
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle', # 匿名用户
'rest_framework.throttling.UserRateThrottle', # 认证用户
],
'DEFAULT_THROTTLE_RATES': {
'anon': '100/hour',
'user': '1000/hour'
}
}
- 可自定义 Scope,针对敏感接口(如登录、短信验证码)设置更严格限制:
ScopedRateThrottle。
- Flask 限流扩展
Flask-Limiter:
from flask_limiter import Limiter
limiter = Limiter(app, key_func=get_remote_address)
@app.route("/login")
@limiter.limit("5 per minute")
def login():
...
- 支持多种存储后端:内存(默认,单进程慎用)、Redis(适用于多进程/分布式)。
- FastAPI 结合
slowapi
slowapi是对limits库的封装,用法类似 Flask-Limiter:
from slowapi import Limiter
from slowapi.util import get_remote_address
limiter = Limiter(key_func=get_remote_address)
app.state.limiter = limiter
@app.get("/protected")
@limiter.limit("10/minute")
async def protected(request: Request):
...
- 网关层限流(生产推荐)
- 使用 Nginx
limit_req_zone和limit_req指令,或 API 网关(Kong、Traefik)统一处理,减轻应用层压力,更适合微服务架构。
最佳实践:
- 分级限流:登录接口 5次/1分钟,数据导出 1次/10分钟,普通 API 可宽松一些。
- 返回清晰的状态码和错误信息(通常 429 Too Many Requests),并附上
Retry-After头。 - 记录限流触发事件,监控异常流量,必要时联动安全阻隔。
三者协同
认证、跨域、限流在工程中往往紧密配合。最合理的层次是:
- 中间件层:处理 CORS(最先处理,避免预检请求 OPTIONS 被拦截)和通用限流。
- 依赖注入/装饰器:处理认证鉴权,紧贴具体视图,实现细粒度控制。
- 网关层:负责全局流控和黑白名单,作为第一道防线。
这样分层后,业务代码保持干净,安全策略又全面可控。