人人都会AI编程

19.5 认证鉴权、跨域处理、接口限流最佳实践

更新时间:2026-07-12

在 Web 开发中,API 的安全性与稳定性离不开三个核心能力:认证鉴权保证“请求来自谁、能不能访问”,跨域处理解决“浏览器同源策略”的阻碍,接口限流防止服务被滥用或击垮。本节结合 Django、Flask、FastAPI 三大框架的常用方案,给出可直接落地的实践指南。

认证鉴权

目标:确认请求者身份(认证)并判断其是否有权限执行操作(鉴权)。
主流方式

  1. Session-Cookie 认证(适合传统 Web 应用)
  • 流程:用户登录后服务器创建 Session,把 Session ID 通过 Cookie 返回给浏览器,后续请求自动携带。
  • 适用场景:前后端不分离的 Django 项目、后台管理系统。
  • 实践要点:设置 Cookie 的 HttpOnlySecure 属性防止 XSS 窃取;启用 CSRF 保护;Session 可存储在 Redis 等外部缓存中,防止单点失效。
  1. Token 认证(适合前后端分离、移动端)
  • 典型实现:JWT(JSON Web Token)。
  • 流程:登录接口验证凭证后,服务器返回一个签名的 JWT;客户端在请求头 Authorization: Bearer <token> 中携带;服务器验证签名、有效期即可识别用户。
  • 优点:无状态,方便扩展。
  • 需要注意的坑:JWT 默认不加密,切勿在 payload 中放敏感信息;Token 过期无法主动撤销,可配合 Redis 维护黑名单实现强制退出。
  1. OAuth2 / OIDC(第三方登录、微服务授权)
  • 场景:允许用户用 GitHub、微信登录,或服务间授权。
  • 方案:使用 Authlib 库简化流程,或直接用云服务(如 Auth0、Firebase Auth)。Django 可用 django-allauth,FastAPI 可直接集成第三方 OIDC 提供者。
  1. 权限控制
  • 简单角色判断:自定义装饰器或中间件,检查用户的角色属性(如 user.is_admin)。
  • 细粒度权限:推荐用 RBAC(基于角色的访问控制)或 ABAC。Flask 可扩展 flask-principal,Django 自带 PermissionGroup 模型,FastAPI 可以结合依赖注入实现策略检查。

最佳实践总结

  • 密码绝不存明文,必须使用 bcryptpasslib 加密。
  • 敏感操作(支付、改密)强制二次验证。
  • 统一在中间件或依赖注入层处理认证,避免在各视图函数中重复编写逻辑。

跨域处理(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 或用户短时间内大量请求,避免服务器资源耗尽或数据被爬取。

落地工具与策略

  1. 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
  1. 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(适用于多进程/分布式)。
  1. 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):
         ...
     
  1. 网关层限流(生产推荐)
  • 使用 Nginx limit_req_zonelimit_req 指令,或 API 网关(Kong、Traefik)统一处理,减轻应用层压力,更适合微服务架构。

最佳实践

  • 分级限流:登录接口 5次/1分钟,数据导出 1次/10分钟,普通 API 可宽松一些。
  • 返回清晰的状态码和错误信息(通常 429 Too Many Requests),并附上 Retry-After 头。
  • 记录限流触发事件,监控异常流量,必要时联动安全阻隔。

三者协同

认证、跨域、限流在工程中往往紧密配合。最合理的层次是:

  • 中间件层:处理 CORS(最先处理,避免预检请求 OPTIONS 被拦截)和通用限流。
  • 依赖注入/装饰器:处理认证鉴权,紧贴具体视图,实现细粒度控制。
  • 网关层:负责全局流控和黑白名单,作为第一道防线。

这样分层后,业务代码保持干净,安全策略又全面可控。