同源策略讲解


前言

在学习同源策略时,我们必须要再次明确浏览器和服务器等关系。浏览器发起请求,服务器接收请求并返回响应。而同源策略是浏览器的安全策略。就相当于浏览器的门,服务器是主人。门是有锁(同源策略)的,只有有钥匙🔑的人才可以进门(也就是跨域问题,就是进门问题)。那钥匙是谁给的呢?就是服务器给的,所以配置跨域资源共享就是服务器配置的。服务器定义了只有哪些网络连接可以访问我的服务器,举个例子:www.baidu.com访问不了谷歌的服务器。


提示:以下是本篇文章正文内容,下面案例可供参考

一、同源策略是什么?

首先明确同源策略是浏览器的安全策略,它是为了防止来自不同源的浏览器的访问造成的安全问题,如:获取用户的账号密码等。
同源的源是什么?
同源的定义包括协议(例如 http 和 https)、域名和端口号,只有在这三者都相同的情况下,两个页面才被认为是同源的。

二、同源策略的限制

同源策略是浏览器为了保护用户隐私和安全而实施的一种安全措施。它限制了前端代码对跨域资源的访问,从而防止恶意网站利用前端代码获取用户的敏感信息或进行其他恶意行为。因此,同源策略可以视为浏览器对前端开发人员的一种安全限制,以保护用户免受潜在的网络攻击。

同源策略主要限制以下几个方面:

  • JavaScript 访问: 不同源的页面不能通过 JavaScript 直接访问对方的 DOM 结构。
  • XMLHttpRequest 请求: 在跨域请求时,浏览器会发送预检请求,只有得到服务器的明确许可,才能发送实际请求。
  • Cookie 读取: JavaScript 不能读取其他源的 Cookie。
  • DOM 存取: 跨域的页面不能操作访问另一个源的 DOM。

三、如何处理跨域请求?

可以利用CORS(跨源资源共享)规避同源策略,进行跨域请求。

后端Springboot项目为例

全局配置
全局配置是指对所有请求都生效的跨域配置。在 Spring Boot 中,可以使用 WebMvcConfigurer 接口来配置全局的跨域支持。

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("https://allowed-domain.com")
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("Origin", "X-Requested-With", "Content-Type", "Accept")
                .allowCredentials(true);
    }
}

上述代码中,addCorsMappings 方法定义了对所有路径的跨域配置。在这个例子中,允许来自 https://allowed-domain.com 的请求,支持的方法有 GET、POST、PUT、DELETE,允许的头部包括 Origin、X-Requested-With、Content-Type、Accept,同时支持携带凭证(Credentials)
补充支持携带凭证:
在前端发起一个跨域请求,同时需要在后端进行用户登录状态的验证。如果不允许携带凭证,浏览器将不会发送 Cookies 和其他身份信息,从而导致无法完成用户的身份验证。

局部配置
局部配置是指对某个具体的请求路径进行跨域配置。可以通过在 Controller 的方法上使用 @CrossOrigin 注解来实现。

@RestController
@RequestMapping("/api")
public class MyController {

    @GetMapping("/data")
    @CrossOrigin(origins = "https://allowed-domain.com", methods = {RequestMethod.GET, RequestMethod.POST})
    public ResponseEntity<String> getData() {
        // 处理业务逻辑
        return ResponseEntity.ok("Data from the server");
    }
}

在上述例子中,@CrossOrigin 注解应用于 getData 方法,指定了允许来自 https://allowed-domain.com 的 GET 和 POST 请求。这样的配置是针对特定接口或路径的,更加灵活。

拦截器配置


@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {

    /**
     * 跨域拦截器
     *
     * @return CorsInterceptor实例
     */
    @Bean
    public CorsInterceptor getCorsInterceptor() {
        return new CorsInterceptor();
    }

    /**
     * 重写addInterceptors方法,添加自定义拦截器
     *
     * @param registry 拦截器注册表
     */
    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        // 将CorsInterceptor拦截器添加到拦截器链中,并指定拦截路径为"/api/v1/**"
        registry.addInterceptor(getCorsInterceptor()).addPathPatterns("/api/v1/**");
        // 调用父类的addInterceptors方法,将自定义的拦截器注册到Spring MVC拦截器链中
        super.addInterceptors(registry);
    }

}

在这个示例中,通过@Configuration注解标记WebMvcConfig类为Spring的配置类。getCorsInterceptor()方法使用@Bean注解标记为Spring容器管理的Bean,用于获取CorsInterceptor实例。addInterceptors()方法重写了父类的方法,在其中将CorsInterceptor拦截器添加到拦截器链中,并指定了拦截路径为"/api/v1/**",使得访问这个路径下的接口会被拦截器处理。

拦截器和配置类的区别
这两种配置都是用于处理跨域请求的,但是它们的实现方式略有不同,适用场景也有所区别:

  1. CorsConfig 类实现 WebMvcConfigurer 接口:
    • 这种方式是通过实现 WebMvcConfigurer 接口,并重写其中的 addCorsMappings 方法来配置跨域访问的规则。
    • addCorsMappings 方法中,可以设置允许跨域访问的原始域(allowedOrigins)、允许的 HTTP 方法(allowedMethods)、允许的请求头(allowedHeaders)、是否允许发送 Cookie(allowCredentials)等参数。
    • 这种方式适用于简单的跨域配置,可以针对不同的 URL 模式进行灵活的配置。
  2. WebMvcConfig 类继承 WebMvcConfigurationSupport 类:
    • 这种方式是通过创建一个 WebMvcConfigurationSupport 的子类,并重写其中的 addInterceptors 方法来添加拦截器。
    • addInterceptors 方法中,将自定义的拦截器添加到拦截器注册表中,并指定拦截的 URL 模式。
    • 这种方式适用于需要对请求进行更加复杂的处理,例如添加拦截器、过滤器等进行权限校验,而不仅仅是简单的跨域配置。

一般来说,如果只需要简单的跨域配置,推荐使用第一种方式,即实现 WebMvcConfigurer 接口;如果需要对请求进行更复杂的处理,可以考虑使用第二种方式,即继承 WebMvcConfigurationSupport 类。


四、跨域的具体步骤

  1. 服务器配置 CORS 头部: 在服务器端的配置中,你会设置哪些域、方法和头部是被允许的,这包括 Access-Control-Allow-OriginAccess-Control-Allow-MethodsAccess-Control-Allow-Headers 等。
  2. 浏览器发送预检请求: 当浏览器检测到跨域请求时,会发送一个 OPTIONS 请求,即预检请求,到目标服务器。
  3. 服务器处理预检请求: 服务器接收到预检请求后,检查请求中的头部信息,包括 Origin、Access-Control-Request-Method、Access-Control-Request-Headers。然后根据服务器配置的 CORS 头部信息,判断是否允许当前域进行实际请求。
  4. 服务器响应预检请求: 服务器返回一个包含 CORS 头部信息的响应,告知浏览器是否允许实际请求。如果允许,浏览器将发送实际请求;如果不允许,浏览器将阻止实际请求的发送。
  5. 浏览器发送实际请求: 如果预检请求得到允许,浏览器将发送实际的请求,该请求携带正常的请求头和数据。

五、一二级域名的关系

跨域请求和一级域名、二级域名之间存在紧密的关系。同源策略要求在进行跨域请求时,不同域之间需要满足一定的条件,而域名的结构中的一级域名和二级域名的差异是在这个背景下显得重要的。

一级域名和二级域名

  • 一级域名(Top-Level Domain,TLD): 一级域名是域名结构中的最高层级,通常表示国家或通用顶级域,例如 .com.org.cn
  • 二级域名(Second-Level Domain,SLD): 二级域名是在一级域名之下的层级,是用户可以注册的主体,例如在 example.com 中,example 是二级域名。

关系和影响

  1. 同源策略限制: 同源策略是浏览器的一项安全策略,要求不同域之间在一些关键属性(协议、域名、端口号)上相同,才被认为是同源。因此,https://example.comhttps://sub.example.com 就属于不同源,会受到同源策略的限制。

  2. Cookie 跨域共享: 一级域名和二级域名之间的关系对于 Cookie 的跨域共享具有影响。通常情况下,浏览器默认情况下不允许不同域之间的 Cookie 共享,但可以通过设置 Cookie 的 Domain 属性来实现一级域名和二级域名之间的共享。

    例如,对于域名 example.com,设置 Cookie 的 Domain.example.com 就可以使其在 sub.example.com 下有效,实现了跨域共享。

htmlCopy code
// 设置 Cookie 的示例
Set-Cookie: key=value; Domain=.example.com; Path=/; Secure; HttpOnly

在实际开发中,了解域名结构和同源策略的关系,以及如何合理配置 Cookie 的 Domain 属性,有助于解决跨域请求和共享数据的问题,提升 Web 应用的灵活性和用户体验。

总结

以上是我个人对于同源策略的简要理解,欢迎各位大佬批评指正、欢迎大家交流学习。

  • 20
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值