概述
跨域资源共享(Cross-Origin Resource Sharing, CORS)是现代Web应用程序中的重要安全机制。本文档旨在提供全面的CORS配置指南,涵盖从开发环境到生产部署的完整实施方案。
技术背景
同源策略基础
同源策略是Web应用安全的基石,要求协议(Protocol)、域名(Domain)和端口(Port)三者均相同。以下为不同场景的示例分析:
1 2 3 4 5 6
| 基准URL:http://example.com/page.html
跨域场景: - http://api.example.com/data // 子域名差异 - https://example.com/data // 协议差异 - http://example.com:8080/data // 端口差异
|
配置方案
环境变量驱动的CORS配置
以下是一个完整的、基于环境变量的CORS配置示例。这种方案具有良好的灵活性和可维护性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import os from flask import Flask from flask_cors import CORS
app = Flask(__name__)
FRONTEND_URL = os.environ.get('FRONTEND_URL', 'http://localhost:3000')
CORS(app, resources={ r"/api/*": { "origins": FRONTEND_URL, "methods": ["GET", "POST", "OPTIONS", "PUT", "DELETE"], "allow_headers": ["Content-Type", "Authorization", "X-Requested-With"], "supports_credentials": True, "expose_headers": ["Content-Disposition"] } })
|
配置详解
让我们逐行分析这个配置:
- 环境变量设置
1
| FRONTEND_URL = os.environ.get('FRONTEND_URL', 'http://localhost:3000')
|
- 使用
os.environ.get()
获取环境变量 - 提供默认值
'http://localhost:3000'
作为本地开发环境的配置 - 可以通过环境变量轻松切换不同环境的配置
- CORS配置参数
- 动态设置允许的源,基于环境变量
- 避免了硬编码的问题
- 支持不同部署环境的灵活配置
- HTTP方法配置
1
| "methods": ["GET", "POST", "OPTIONS", "PUT", "DELETE"]
|
- 明确定义允许的HTTP方法
- 包含了RESTful API所需的全部方法
OPTIONS
用于预检请求(preflight request)
- 请求头配置
1
| "allow_headers": ["Content-Type", "Authorization", "X-Requested-With"]
|
Content-Type
:允许设置请求的内容类型Authorization
:支持身份验证令牌X-Requested-With
:用于标识AJAX请求
- 凭证支持
1
| "supports_credentials": True
|
- 允许跨域请求携带凭证(如Cookie)
- 对需要身份验证的API至关重要
- 响应头暴露
1
| "expose_headers": ["Content-Disposition"]
|
- 允许客户端访问
Content-Disposition
响应头 - 通常用于文件下载功能
环境变量配置示例
1 2 3 4 5 6 7 8
| export FRONTEND_URL=http://localhost:3000
export FRONTEND_URL=http://test.example.com
export FRONTEND_URL=https://www.example.com
|
最佳实践
环境变量管理建议
- 开发环境
- 使用
.env
文件管理本地开发环境变量 - 将
.env
文件加入.gitignore
- 生产环境
- 使用容器化部署时通过环境变量注入
- 使用配置管理系统统一管理环境变量
安全性考虑
- 避免过于宽松的配置
1 2 3 4 5
| "origins": "*"
"origins": FRONTEND_URL
|
- 合理设置凭证策略
- 仅在必要时启用
supports_credentials
- 确保前端配置匹配(
credentials: 'include'
)
问题排查
常见错误及解决方案
- CORS策略违规
1 2
| Access to XMLHttpRequest at 'http://api.example.com' from origin 'http://example.com' has been blocked by CORS policy
|
解决方案:
- 检查环境变量是否正确设置
- 验证前端请求URL与配置是否匹配
- 确认所有必要的请求头都已配置
参考文献
- W3C CORS Specification
- MDN Web Docs - Cross-Origin Resource Sharing
- Flask-CORS Official Documentation