一、问题
在SpringBoot项目中,明确指定仅允许指定网站跨域访问:
为什么开发人员却仍旧可以通过HTTP工具调用接口?
二、为什么
在回答这个问题之前,我们首先要了解一下什么是CORS!
1、什么是CORS
CORS的全称为跨域资源共享(Cross-Origin Resource Sharing,简称 CORS),是服务器为浏览器提供的一种跨域资源共享安全机制。
通过CORS机制,服务器可以声明允许浏览器从一个不同于当前网页所在的域中请求资源、拒绝不符合的非法请求,防止恶意网站从被用户信任的站点获取敏感数据。
具体来说,浏览器在处理跨域请求时,会自动添加 Origin 头部字段并进行一系列的安全检查(比如预检请求),从而保护用户免受潜在的跨域攻击。
当我们使用 Postman 等工具发送HTTP请求时,则仅仅发送请求而不会自动添加Origin请求头或发送预检查请求等安全检查行为,因此将被服务器认为是同源请求而绕过CORS检查。
简单来说,CORS机制是服务器通过Origin请求头或预检查的方式为浏览器提供跨域资源共享的一种限制性安全保护机制,而开发人员通过Postman等工具发送HTTP请求时则由于服务器没有检测到Origin请求头等信息而以同源请求处理,因而使得请求被服务器成功受理。
2、CORS工作机制
浏览器是如何通过CORS机制实现安全的跨域资源共享、限制非法跨域请求呢?具体来说可以分以下两个方面:
1) 简单请求(Simple Request)
- 仅支持GET、HEAD和POST方法。
- 自定义请求头限制为:Accept、Accept-Language、Content-Language、Content-Type(值仅限于application/x-www-form-urlencoded、multipart/form-data、text/plain)。
- 浏览器会自动添加 Origin 请求头,表明请求来自哪个来源。
- 服务器可以通过响应头 Access-Control-Allow-Origin 指定允许的来源,浏览器会检查这个头,如果匹配,则允许访问,否则拒绝。
2) 预检请求(Preflight Request)
- 用于复杂请求(如使用了 PUT、DELETE 方法或带有自定义头)。
- 浏览器首先发起一个 OPTIONS 请求,称为“预检请求”,来询问服务器是否允许实际请求。
- 服务器如果允许,则返回相关的 CORS 响应头,浏览器根据这些头信息决定是否发送实际请求。
三、怎么验证
理解了跨域请求的工作机制,那么在开发工作过程中,我们怎么调测验证跨域的有效性呢?
根据浏览器与CORS的工作机制,我们可以在HTTP请求头手动添加 Origin
熟悉属性来模拟跨域请求,进而观测服务器的 CORS 配置和响应行为。
1、跨域请求失败
请求头Origin的值http://test.com不在CORS声明的允许匹配地址范围内,因此请求被拒绝,返回403 Forbidden
2、跨域请求成功
请求头Origin地址匹配到了CORS声明允许的规则,跨域请求成功,返回响应头包含成功的跨域请求信息。
四、总结
1、CORS是服务器提供浏览器用于跨域资源共享的一种安全保护机制;
2、浏览器通过自动添加请求头Origin或发送OPTIONS预检查请求,配合服务器的CORS机制实现跨域资源请求的安全共享;
3、开发人员可以通过手动添加Origin请求头的方式,模拟跨域HTTP请求;
五、题外话
1、同源策略(Same-Origin Policy)
浏览器通过“同源策略”判断在网页中的一个资源请求是否跨域。
同源策略(Same-Origin Policy)要求网页中加载的资源(如脚本、样式表、图像等)必须来自于相同的域、协议和端口,即源(origin)必须完全相同。
一个 URL 的源由协议、域名和端口号组成,如果网页中某个资源 URL 的这三者中任何一个不同,则被认为是不同源。
- 协议(Protocol): 请求的协议(例如 http:// 或 https://)必须与目标资源的协议一致。
- 域名(Domain): 请求的域名或主机名必须与目标资源的域名或主机名一致。
- 端口(Port): 如果请求使用了非标准端口(例如 http://example.com:8080),则目标资源的端口也必须与之匹配。
具体来说,浏览器通过以下检查来判断请求是否来自不同源的资源:
- 如果请求的协议、域名和端口与页面所在的源完全一致,则被视为同源请求。
- 如果任何一个因素(协议、域名、端口)与页面所在的源不一致,则被视为跨源请求。
同源策略(Same-Origin Policy)是浏览器的一项重要安全策略,用于防止未授权的跨域数据访问,主要目的是保护用户数据的安全和隐私。
- 保护用户数据安全:如果没有同源策略,恶意网站可以在用户不知情的情况下,通过脚本访问其他网站的数据,如用户的个人信息、Cookie 等,造成数据泄露和滥用。
- 防止跨站请求伪造(CSRF):同源策略可以防止恶意网站利用已登录用户的凭据(如 Cookie)来伪造用户身份,在其他网站上执行未授权的操作。
- 防止脚本劫持:通过限制不同源之间的脚本交互,可以减少被恶意脚本劫持的风险,保护网站的正常运行和用户体验。
2、重要的 CORS 响应头
-
Access-Control-Allow-Origin:指定哪些域可以访问资源。例如,
Access-Control-Allow-Origin: https://example.com
或Access-Control-Allow-Origin: *
(允许所有域)。 -
Access-Control-Allow-Methods:指定允许的 HTTP 方法,例如
GET, POST, PUT, DELETE
。 -
Access-Control-Allow-Headers:指定允许的请求头,例如
Content-Type, Authorization
。 -
Access-Control-Allow-Credentials:指示是否允许发送 Cookie 和 HTTP 认证信息。设置为
true
时,必须明确指定Access-Control-Allow-Origin
的值,不能使用通配符*
。 -
Access-Control-Expose-Headers:指定哪些响应头可以暴露给外部 JavaScript 代码。
-
Access-Control-Max-Age:指示浏览器可以缓存预检请求结果的时间,以秒为单位。
3、参考链接CORS
关于CORS的官方链接参考:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS