Become a sponsor

说明
CORS(Cross-Origin Resource Sharing)跨域资源共享是前后端分离架构必须处理的问题。通过 TORNADO_CORS_ORIGINS 环境变量配置允许的跨域源。实现位于 src/common/middleware/cors.py,在 BaseHandler.set_default_headers() 中调用。
| 环境变量 | 默认值 | 说明 |
|---|---|---|
TORNADO_CORS_ORIGINS | 空(允许所有源) | 允许的跨域源(逗号分隔) |
# .env
# 允许所有源(开发环境)
TORNADO_CORS_ORIGINS=
# 允许指定源(生产环境)
TORNADO_CORS_ORIGINS=https://admin.example.com,https://www.example.com生产环境
生产环境务必配置 TORNADO_CORS_ORIGINS 为具体域名,避免允许所有源带来的安全风险。
# src/common/middleware/cors.py
from config.app import TORNADO_CORS_ORIGINS
# 解析白名单(逗号分隔)
_ALLOWED_ORIGINS = {o.strip() for o in TORNADO_CORS_ORIGINS.split(",") if o.strip()}
def cros_required(self):
"""为响应设置跨域相关头。"""
origin = self.request.headers.get("Origin", "")
# 配置了白名单:仅对匹配来源反射来源并允许携带凭据
if _ALLOWED_ORIGINS:
if origin in _ALLOWED_ORIGINS:
self.set_header("Access-Control-Allow-Origin", origin)
self.set_header("Access-Control-Allow-Credentials", "true")
self.set_header("Vary", "Origin")
else:
# 未配置白名单:允许所有来源(不携带凭据)
self.set_header("Access-Control-Allow-Origin", "*")
# 安全相关响应头
self.set_header("X-XSS-Protection", "1; mode=block")
self.set_header("Content-Security-Policy", "default-src 'self'")
# 允许的请求头和方法
self.set_header("Access-Control-Allow-Headers", "*")
self.set_header("Access-Control-Expose-Headers", "*")
self.set_header("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS")
self.set_header("Content-Type", "application/json; charset=UTF-8")
# 预检请求最大缓存时间(秒)
self.set_header("Access-Control-Max-Age", "3600")CORS 在 BaseHandler.set_default_headers() 中调用,每个请求自动设置:
# src/core/base_handler.py
class BaseHandler(tornado.web.RequestHandler):
def set_default_headers(self):
super().set_default_headers()
cros_required(self) # 设置 CORS 头
apply_trace_id(self) # 设置 TraceID| 响应头 | 说明 |
|---|---|
Access-Control-Allow-Origin | 允许的来源(* 或具体域名) |
Access-Control-Allow-Credentials | 是否允许携带凭据(Cookie 等) |
Access-Control-Allow-Methods | 允许的 HTTP 方法 |
Access-Control-Allow-Headers | 允许的请求头 |
Access-Control-Expose-Headers | 允许前端读取的响应头 |
Access-Control-Max-Age | 预检请求缓存时间(秒) |
Vary | 缓存键(白名单模式下使用) |
浏览器对跨域复杂请求(如 PUT/DELETE 或携带自定义 Header)会先发送 OPTIONS 预检请求。BaseHandler.options() 直接返回 204:
# src/core/base_handler.py
class BaseHandler(tornado.web.RequestHandler):
def options(self, *args, **kwargs):
"""处理 CORS 预检请求,直接返回 204 无内容响应。"""
self.set_status(204)
self.finish()CORS 跨域配置具备以下特点:
1. 环境变量配置:通过 TORNADO_CORS_ORIGINS 灵活配置允许的源
2. 开发/生产分离:开发环境允许所有源,生产环境指定域名
3. 安全默认:未配置时允许所有源但不携带凭据
4. 自动生效:在 BaseHandler.set_default_headers() 中调用,每个请求自动设置
5. 预检处理:OPTIONS 请求直接返回 204,不进入业务逻辑