简单介绍跨域资源共享(CORS)
一、跨域问题的机制
1.1 跨域限制
- 浏览器实施的安全策略:同源策略(Same-Origin Policy)由浏览器强制执行
- 保护对象 :主要保护客户端(用户) 的数据安全,防止:
- 恶意网站窃取用户在其他站点的敏感数据
- 滥用用户登录凭证(如Cookies)
- 进行未经授权的操作
- 服务器角色:服务器本身没有跨域限制,任何客户端(Postman/cURL)都可直接访问
1.2 跨域解决方案对比
方案 | 原理 | 适用场景 | 限制 |
---|---|---|---|
JSONP | 利用<script> 标签无跨域限制 |
仅GET请求 | 不安全、功能有限 |
CORS | 服务端设置响应头授权 | 所有HTTP方法 | 需服务端配合 |
代理 | 同源服务端转发请求 | 开发环境/无权限改后端 | 增加服务器负担 |
二、CORS核心响应头详解
2.1 基础控制头
响应头 | 作用 | 示例值 |
---|---|---|
Access-Control-Allow-Origin |
指定允许访问资源的源(必选) | https://your-site.com 或 * |
Access-Control-Allow-Methods |
声明允许的HTTP方法(预检请求必需) | GET, POST, PUT, DELETE |
Access-Control-Allow-Headers |
声明允许的请求头(预检请求必需) | Content-Type, Authorization |
2.2 高级控制头
响应头 | 作用 | 示例值 |
---|---|---|
Access-Control-Allow-Credentials |
是否允许发送凭证(cookies/HTTP认证) | true |
Access-Control-Expose-Headers |
指定客户端可访问的响应头(默认仅开放基础头) | X-Custom-Header |
Access-Control-Max-Age |
预检请求缓存时间(秒),减少OPTIONS请求 | 86400 (24小时) |
三、Access-Control-Allow-Credentials解析
3.1 使用场景
- 跨域身份认证(Session/Cookie)
- 携带授权令牌(JWT)的API请求
- 需要用户凭证的敏感操作
3.2 基本配置
服务端配置:
javascript
// Node.js/Express示例
app.use((req, res, next) => {
const allowedOrigins = ['https://client-app.com', 'https://admin.client-app.com'];
const origin = req.headers.origin;
if (allowedOrigins.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Access-Control-Allow-Credentials', 'true');
}
// 处理预检请求
if (req.method === 'OPTIONS') {
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
return res.status(204).end();
}
next();
});
客户端配置:
javascript
// 使用Fetch API
fetch('https://api.example.com/data', {
credentials: 'include' // 关键配置
});
// 使用Axios
axios.get('https://api.example.com/data', {
withCredentials: true // 关键配置
});
Cookie安全设置:
http
Set-Cookie: sessionId=abc123;
SameSite=None; // 允许跨站携带
Secure; // 仅HTTPS传输
HttpOnly; // 防止XSS读取
Max-Age=3600; // 合理有效期
四、CORS请求类型处理
4.1 简单请求
特征:
- 方法为GET/POST/HEAD
- Content-Type为:text/plain, application/x-www-form-urlencoded, multipart/form-data
- 无自定义头
处理 :只需设置Access-Control-Allow-Origin
4.2 复杂请求(触发预检)
特征:
- PUT/DELETE等方法
- Content-Type: application/json
- 自定义头(如Authorization)
处理流程:

五、相对安全的方法
5.1 配置安全原则
-
避免通配符与凭证共存:
http// ❌ 危险配置 Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: true // ✅ 安全配置 Access-Control-Allow-Origin: https://trusted-domain.com Access-Control-Allow-Credentials: true
-
动态源验证:
javascriptconst allowedOrigins = ['https://your-site.com', 'https://admin.your-site.com']; const requestOrigin = req.headers.origin; if (allowedOrigins.includes(requestOrigin)) { res.setHeader('Access-Control-Allow-Origin', requestOrigin); }
5.2 防御纵深策略
安全层 | 实施措施 |
---|---|
CORS层 | 严格限制Allow-Origin、Allow-Methods、Allow-Headers |
认证层 | JWT过期时间设置、刷新令牌机制 |
会话层 | Cookie设置HttpOnly、Secure、SameSite=None |
业务层 | 敏感操作要求二次验证(短信/邮件验证码) |
监控层 | 记录异常OPTIONS请求、监控Origin头伪造行为 |
六、常见问题解决方案
6.1 高频错误排查
错误信息 | 解决方案 |
---|---|
Credentials mode is 'include' but Allow-Origin is '*' |
使用具体域名代替通配符 |
Cookie not sent due to SameSite policy |
设置Cookie: SameSite=None; Secure |
Response header 'X-Custom-Header' is not allowed |
添加:Access-Control-Expose-Headers: X-Custom-Header |
Method PUT is not allowed by Access-Control-Allow-Methods |
预检响应中添加:Access-Control-Allow-Methods: PUT |
6.2 本地开发解决方案
javascript
// Create-React-App代理配置(vite.config.js/react-scripts同理)
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
})
七、CORS在现代架构中的应用
7.1 微服务架构
graph LR
A[客户端] --> B[API网关]
B --> C[用户服务]
B --> D[订单服务]
B --> E[支付服务]
style A fill:#f9f,stroke:#333
style B fill:#bbf,stroke:#333
最佳实践:在API网关统一处理CORS策略,避免各服务重复配置
7.2 跨域单点登录(SSO)
javascript
// 认证中心CORS配置
app.post('/sso/login', (req, res) => {
res.cookie('sso_token', token, {
secure: true,
sameSite: 'none',
httpOnly: true
});
res.setHeader('Access-Control-Allow-Origin', 'https://app.company.com');
res.setHeader('Access-Control-Allow-Credentials', 'true');
res.json({ redirect: '/dashboard' });
});
结论:CORS安全实施三要素
-
精确控制:
- 严格限制Allow-Origin为可信域名
- 按需开放HTTP方法和请求头
- 合理设置预检缓存时间
-
凭证安全:
- 遵循"具体域名+Allow-Credentials+客户端withCredentials"三位一体
- Cookie设置SameSite=None+Secure+HttpOnly
- 敏感操作添加二次验证
-
纵深防御:
- CORS不是唯一安全防线
- 结合CSRF令牌、速率限制、操作审计
- 定期审查和更新CORS策略
正确理解和实施CORS,能在保障安全的前提下释放Web应用的跨域能力,构建真正现代化的网络应用生态系统。