• CORS--跨域资源共享


    CORS 是一个 W3C 标准,全称是”跨域资源共享”(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出 XMLHttpRequest 请求,从而克服了 AJAX 只能同源使用的限制。但同时也会带来安全的隐患,其中最主要的隐患来自于CSRF(Cross-site request forgery)跨站请求伪造。

    1、浏览器的同源策略

    浏览器将 CORS 请求分成了简单请求和非简单请求

    简单请求条件如下,不满足则为非简单请求。对于非简单请求的跨源请求,浏览器会在真实请求发出前,增加一次OPTION请求,称为预检请求(preflight request)。预检请求将真实请求的信息,包括请求方法、自定义头字段、源信息添加到 HTTP 头信息字段中,询问服务器是否允许这样的操作。

    2、CORS配置

    • 1、如果想要对某一接口配置 CORS,可以在方法上添加 @CrossOrigin 注解 :
    @CrossOrigin(origins = {"http://localhost:9000", "null"})
    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public String greetings() {
        return "{"project":"just a test"}";
    }
    • 2、如果想对一系列接口添加 CORS 配置,可以在类上添加注解,对该类声明所有接口都有效:
    @CrossOrigin(origins = {"http://localhost:9000", "null"})
    @RestController
    @SpringBootApplication
    public class SpringBootCorsTestApplication {
        
    }
    • 3、如果想添加全局配置,则需要添加一个配置类 :
    @Bean
        public WebMvcConfigurer corsConfigurer() {
            return new WebMvcConfigurer() {
                @Override
                public void addCorsMappings(CorsRegistry registry) {
                    // 跨域设置
                    registry.addMapping("/**").allowedOrigins("*");
                }
            };
        }

    另外,还可以通过添加 Filter 的方式,配置 CORS 规则,并手动指定对哪些接口有效。

    @Bean
    public FilterRegistrationBean corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);   
    config.addAllowedOrigin("*"); source.registerCorsConfiguration("/**", config); // CORS 配置对所有接口都有效 FilterRegistrationBean bean = newFilterRegistrationBean(new CorsFilter(source)); bean.setOrder(0); return bean; }

    3、原理解析

    无论是通过哪种方式配置 CORS,其实都是在构造 CorsConfiguration。 一个 CORS 配置用一个 CorsConfiguration类来表示,它的定义如下:

    public class CorsConfiguration {
        private List<String> allowedOrigins;
        private List<String> allowedMethods;
        private List<String> allowedHeaders;
        private List<String> exposedHeaders;
        private Boolean allowCredentials;
        private Long maxAge;
    }

    Spring 中对 CORS 规则的校验,都是通过委托给 DefaultCorsProcessor实现的。

    DefaultCorsProcessor 处理过程如下:

    1. 判断依据是 Header中是否包含 Origin。如果包含则说明为 CORS请求,转到 2;否则,说明不是 CORS 请求,不作任何处理。
    2. 判断 response 的 Header 是否已经包含 Access-Control-Allow-Origin,如果包含,证明已经被处理过了, 转到 3,否则不再处理。
    3. 判断是否同源,如果是则转交给负责该请求的类处理
    4. 是否配置了 CORS 规则,如果没有配置,且是预检请求,则拒绝该请求,如果没有配置,且不是预检请求,则交给负责该请求的类处理。如果配置了,则对该请求进行校验。

    4、配置项解析

    1 Access-Control-Allow-Origin
    该字段必填。它的值要么是请求时Origin字段的具体值,要么是一个*,表示接受任意域名的请求。

    2 Access-Control-Allow-Methods
    该字段非简单请求时必填。它的值是逗号分隔的一个具体的字符串或者*,表明服务器支持的所有跨域请求的方法。注意,返回的是所有支持的方法,而不单是浏览器请求的那个方法。这是为了避免多次"预检"请求。

    3 Access-Control-Expose-Headers
    4.3 该字段可选。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。

    4 Access-Control-Allow-Credentials
    该字段可选。它的值是一个布尔值,表示是否允许发送Cookie.默认情况下,不发生Cookie,即:false。对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json,这个值只能设为true。如果服务器不要浏览器发送Cookie,删除该字段即可。

    5 Access-Control-Max-Age
    该字段可选,用来指定本次预检请求的有效期,单位为秒。在有效期间,不用发出另一条预检请求。 

  • 相关阅读:
    [Leetcode] Longest Substring Without Repeating Characters
    [Leetcode] Clone Graph
    [Leetcode] LRU Cache
    行转列
    微信 Demo
    微信开发-step by stemp
    知识库
    SSAS GUID 添加 行计数,非重复计数 等 遇到的莫名其妙的问题
    javascript 前段MVVM 框架
    微信接口开发
  • 原文地址:https://www.cnblogs.com/pjfmeng/p/11233295.html
Copyright © 2020-2023  润新知