cors

同源策略(Same-Origin Policy)

同源策略是浏览器的一种安全机制,用于防止不同源的资源互相访问,从而避免安全隐患。所谓“同源”,是指以下三个属性完全相同:

  1. 协议(Protocol),如 httphttps
  2. 域名(Domain),如 example.com
  3. 端口(Port),如 80443

例如,http://example.com/pagehttp://example.com/other-page 是同源的,但 http://example.comhttp://another-example.com 是不同源的。

跨域请求

当一个网页试图从另一个域(不同的协议、域名或端口)加载资源(如图片、CSS、脚本、AJAX请求等)时,就会发生跨域请求。如果没有特殊处理,浏览器会阻止这种请求,以保护用户信息安全。

为什么会产生跨域问题?

跨域问题是由于浏览器的同源策略引起的。浏览器出于以下几种考虑,默认阻止跨域请求:

  1. 防止XSS攻击:跨站脚本攻击(Cross-Site Scripting,XSS)是指攻击者注入恶意脚本到另一个网页中。浏览器的同源策略可以防止这种攻击。
  2. 防止CSRF攻击:跨站请求伪造(Cross-Site Request Forgery,CSRF)是指攻击者诱导用户在已认证的会话中执行非预期的操作。同源策略也可以防止这种攻击。
  3. 数据安全性:同源策略确保一个网页不能随意读取另一个网页的敏感数据,从而保护用户隐私。

安全性和可用性需要一个平衡点

cross origin resource sharing

CORS请求的类型

  1. 简单请求(Simple Requests)

    • 使用以下方法之一:GETPOSTHEAD
    • 头部仅限于:AcceptAccept-LanguageContent-LanguageContent-Type
    • 且值限于 application/x-www-form-urlencodedmultipart/form-datatext/plain

    这种请求会直接发送,但浏览器会检查响应头中的 Access-Control-Allow-Origin 来决定是否允许跨域。

  2. 预检请求(Preflight Requests)

    • 使用除 GETPOSTHEAD 之外的方法,或自定义头部,或 Content-Type 值不在上述范围内。
    • 浏览器会先发送一个 OPTIONS 请求,询问服务器是否允许跨域。如果服务器允许,浏览器才会发送实际请求。

CORS响应头

服务器通过设置以下头部来控制跨域请求:

  • Access-Control-Allow-Origin:指定允许哪些源访问资源。例如,* 表示允许所有源。
  • Access-Control-Allow-Methods:指定允许的HTTP方法。
  • Access-Control-Allow-Headers:指定允许的自定义头部。
  • Access-Control-Allow-Credentials:指示是否允许发送Cookie和HTTP认证信息。
  • Access-Control-Max-Age:指示预检请求的结果可以被缓存多长时间。

CORS 请求的完整示例

以下是一个完整的CORS请求示例,包含预检请求和实际请求:

预检请求(Preflight Request)

1
2
3
4
5
http复制代码OPTIONS /api/data HTTP/1.1
Host: api.example.com
Origin: http://example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, X-Custom-Header

预检响应(Preflight Response)

1
2
3
4
5
http复制代码HTTP/1.1 204 No Content
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: Content-Type, X-Custom-Header
Access-Control-Max-Age: 3600

实际请求(Actual Request)

1
2
3
4
5
6
7
8
9
10
http复制代码POST /api/data HTTP/1.1
Host: api.example.com
Origin: http://example.com
Content-Type: application/json
X-Custom-Header: CustomValue

{
"name": "John",
"email": "john@example.com"
}

实际响应(Actual Response)

1
2
3
4
5
6
7
http复制代码HTTP/1.1 200 OK
Content-Type: application/json
Access-Control-Allow-Origin: http://example.com

{
"message": "Data received successfully"
}

详细解释

  1. 预检请求(Preflight Request)
    • 浏览器发送 OPTIONS 请求,询问服务器是否允许实际的跨域请求。
    • 包含 Access-Control-Request-MethodAccess-Control-Request-Headers,告知服务器实际请求的 HTTP 方法和自定义头部。
  2. 预检响应(Preflight Response)
    • 服务器响应中包含 Access-Control-Allow-Origin 以允许的源。
    • Access-Control-Allow-Methods 列出允许的 HTTP 方法。
    • Access-Control-Allow-Headers 列出允许的自定义头部。
    • Access-Control-Max-Age 指示预检请求的结果可以被缓存的时间(以秒为单位)。
  3. 实际请求(Actual Request)
    • 浏览器在预检通过后发送实际的请求。
    • 包含 Origin 头部指示请求的源。
    • 可能包含自定义头部和请求体。
  4. 实际响应(Actual Response)
    • 服务器处理实际请求并返回响应。
    • 响应中包含 Access-Control-Allow-Origin 头部以指示允许的源。

cors
http://example.com/2024/06/01/cors/
作者
Forrest
发布于
2024年6月1日
许可协议