CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Web 与安全入门/课时/CORS
RawBlame
课时目录12 节

Web 与安全入门

  1. 01Web 安全概览
  2. 02OWASP 风险
  3. 03SSL/TLS
  4. 04CORS
  5. 05CSP 内容安全策略
  6. 06服务器安全
  7. 07密码哈希
  8. 08Basic 认证
  9. 09令牌认证
  10. 10Cookie 认证
  11. 11SAML 简介
  12. 12综合练习

CORS

同源策略、预检;对照 Spring CORS。

25 分钟

CORS

浏览器 同源策略 默认禁止 https://app.example.com 的 JavaScript 读取 https://api.example.com 的响应——即使 API 本身对 curl 完全开放。CORS(Cross-Origin Resource Sharing) 是服务器通过 响应头 声明「哪些跨域前端可以读我的响应」。后端工程师必须分清:CORS 不是认证,它 不阻止 非浏览器客户端直接调 API。

学习目标

  • 说清「简单请求」与「预检 OPTIONS」的差异
  • 在 Spring Boot 中配置 CORS,并与 http-cors 协议细节对照
  • 避免 Access-Control-Allow-Origin: * 与凭据携带的组合陷阱

同源是什么

协议 + 域名 + 端口 三者相同才同源:

页面来源API是否跨域
https://a.comhttps://a.com/api否
https://a.comhttps://api.a.com是
http://a.com:3000http://a.com:8080是(端口不同)

Postman、服务器间调用不受 CORS 限制——所以 API 仍要 认证与授权(sb-security)。

简单请求 vs 预检

简单请求(如 GET、部分 POST):浏览器直接发,服务器用响应头决定是否允许前端 JS 读 body。

预检请求:带自定义头、PUT/DELETE、非简单 Content-Type 等时,浏览器 先发 OPTIONS:

OPTIONS /api/users HTTP/1.1
Origin: https://app.example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Authorization, Content-Type

服务器应返回:

Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type
Access-Control-Max-Age: 86400

Spring @CrossOrigin 或 CorsConfigurationSource 需 正确处理 OPTIONS,否则前端报 CORS 错误但 curl 正常——典型「只有浏览器坏」问题。

Spring Boot 配置示例

@Configuration
public class CorsConfig {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/api/**")
                    .allowedOrigins("https://app.example.com")
                    .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                    .allowedHeaders("Authorization", "Content-Type")
                    .allowCredentials(true)
                    .maxAge(3600);
            }
        };
    }
}

生产环境 显式列出 origin,不要用 * 配合 allowCredentials(true)——规范禁止,浏览器会拒绝。

常见误区

误区事实
「开了 CORS 就安全」只影响浏览器 JS;攻击者用脚本外工具直接打 API
「CORS 能防 CSRF」CSRF 靠 SameSite Cookie、token、双重提交等(见 sec-auth-cookie)
「后端不用改,前端 proxy 就行」开发 proxy 可行;生产仍需 API 对真实前端域名放行
Allow-Origin: * 省事无法带 Cookie 凭据;多租户 SaaS 易配错

与 Cookie / Token 认证

  • Cookie 会话:跨域要带 Cookie 时,需 credentials: 'include' + Allow-Credentials: true + 具体 Origin(非 *)
  • Bearer Token:通常放 Authorization 头,仍可能触发预检;确保 Allow-Headers 含 Authorization

OAuth 授权码流涉及 多个域(见 oauth-flows),CORS 与 redirect URI 要 一起设计,不要各配各的。

调试 checklist

  • DevTools Network 里是否有 OPTIONS 200?
  • 响应头 Access-Control-Allow-Origin 是否与请求 Origin 一致?
  • Spring Security 是否拦截了 OPTIONS?(应 permitAll 或纳入 CORS 配置)
  • 网关 / CDN 是否剥掉了 CORS 头?

练习

  • 用 curl 模拟预检:curl -X OPTIONS -H "Origin: http://localhost:3000" -H "Access-Control-Request-Method: PUT" -v http://localhost:8080/api/demo
  • 对照 http-cors 画「简单请求 vs 预检」时序图
  • 检查项目中是否存在 allowedOrigins("*") 与 allowCredentials(true) 同存

小结

CORS 管浏览器读响应,不管 API 是否该被调用。 下一课 CSP:在 HTML 层限制脚本来源,减轻 XSS 伤害。

加载本节练习…
← 上一课SSL/TLS下一课 →CSP 内容安全策略