简单介绍跨域资源共享(CORS)

简单介绍跨域资源共享(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 配置安全原则

  1. 避免通配符与凭证共存

    http 复制代码
    // ❌ 危险配置
    Access-Control-Allow-Origin: *
    Access-Control-Allow-Credentials: true
    
    // ✅ 安全配置
    Access-Control-Allow-Origin: https://trusted-domain.com
    Access-Control-Allow-Credentials: true
  2. 动态源验证

    javascript 复制代码
    const 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安全实施三要素

  1. 精确控制

    • 严格限制Allow-Origin为可信域名
    • 按需开放HTTP方法和请求头
    • 合理设置预检缓存时间
  2. 凭证安全

    • 遵循"具体域名+Allow-Credentials+客户端withCredentials"三位一体
    • Cookie设置SameSite=None+Secure+HttpOnly
    • 敏感操作添加二次验证
  3. 纵深防御

    • CORS不是唯一安全防线
    • 结合CSRF令牌、速率限制、操作审计
    • 定期审查和更新CORS策略

正确理解和实施CORS,能在保障安全的前提下释放Web应用的跨域能力,构建真正现代化的网络应用生态系统。

相关推荐
pe7er6 分钟前
使用RealFaviconGenerator.net一站式生成各平台兼容 Favicon
前端
用户2519162427117 分钟前
Canvas之贪吃蛇
前端·javascript·canvas
一枚前端小能手9 分钟前
🔥 TypeScript高手都在用的4个类型黑科技
前端·typescript
Elieal14 分钟前
深入浅出:Ajax 与 Servlet 实现前后端数据交互
前端·ajax·servlet
王者鳜錸23 分钟前
VUE+SPRINGBOOT从0-1打造前后端-前后台系统-文章详情、评论、点赞
前端·vue.js·spring boot
乐予吕24 分钟前
别再乱用箭头函数了!JavaScript 三种函数写法的终极指南
前端·javascript·代码规范
雨绸缪25 分钟前
编程之路:我为什么要编程
前端·程序员
一大树29 分钟前
Vue 3 中 `ref` 的“浅监听”行为解析:是误解还是真相?
前端·vue.js
海天胜景30 分钟前
vue3 el-select 加载内容后 触发事件
前端·javascript·vue.js
小高00744 分钟前
🚀Promise 全家桶:原理、实现、API、实战,一篇搞定
前端·javascript·面试