Подробное объяснение решения междоменного доступа к приложению SpringBoot

Spring Boot

1. Что такое междоменный доступ

Когда дело доходит до междоменного доступа, мы должны сначала объяснить термин: политика одного и того же происхождения. Так называемая политика того же происхождения означает, что из соображений безопасности на стороне браузера запрос к серверу должен соответствовать условиям того же протокола, того же хоста (ip) и того же порта, иначе доступ будет запрещен. , а доступ еще называют трансграничным.Домен доступа. Несмотря на то, что междоменный доступ запрещен, безопасность приложения может быть в определенной степени улучшена, но это также вносит определенные трудности в разработку. Например: мы разрабатываем простое в использовании разделение интерфейса и сервера.Страница и js развертываются в службе nginx хоста, а интерфейс сервера развертывается в контейнере приложения tomcat. end инициирует запрос к серверной части, он не должен соответствовать той же политике origin, доступ к нему недоступен. Так как же решить эту проблему? Вот что эта статья должна вам сказать.

2. Какие существуют решения для междоменного доступа?

2.1 Первая категория решений: интерфейсные решения

Хотя браузеры запрещают доступ, который не соответствует политике того же источника, все же есть исключения, такие как следующие теги ссылок на ресурсы, которые не ограничены политикой того же источника:

  • тег html-скрипта
  • html тег ссылки
  • HTML-тег img
  • HTML IFrame Tag: Для проектов, разработанных с JSP и FreeMarker, это наиболее распространенный способ доступа к перекрестному домену.

Помимо реализации междоменного доступа на основе характеристик самого HTML, мы также можем использовать jsonp и postMessage окна для обеспечения междоменного доступа. Это все способы, с помощью которых внешний интерфейс может обеспечить междоменный доступ.

2.2 Второй тип схемы: использование прокси

На самом деле поддержку междоменного доступа проще реализовать на стороне сервера, самый распространенный способ — через прокси, например:

  • Междоменный прокси-сервер nginx или haproxy
  • кросс-доменный прокси-сервер промежуточного программного обеспечения nodejs

На самом деле, логика реализации кросс-доменного прокси очень проста: это построение промежуточного слоя перед различными службами ресурсов: ресурсы js, ресурсы html, ресурсы css, службы ресурсов данных интерфейса, и весь доступ браузера и клиента пересылается через прокси. Таким образом, с точки зрения браузеров и клиентов, они получают доступ к ресурсам с одним и тем же IP-адресом и одним и тем же портом, таким образом обеспечивая междоменный доступ в соответствии с политикой одного и того же источника.

2.3 Третий тип схемы: CORS

Совместное использование ресурсов между источниками (CORS): междоменное взаимодействие достигается путем изменения заголовка протокола Http. Проще говоря, устанавливая информацию заголовка ответа HTTP, браузер информируется о том, какие условия могут быть доступны в разных доменах без соответствия политике одного и того же источника.Браузер выполняет конкретные суждения, анализируя заголовок в протоколе HTTP. Конкретный заголовок выглядит следующим образом:

Общий междоменный заголовок CORS

  • Access-Control-Allow-Origin: к каким IP-адресам или доменным именам разрешен доступ через домены.
  • Access-Control-Max-Age: указывает количество секунд, в течение которых разрешение на междоменный доступ запроса не нужно проверять повторно.
  • Access-Control-Allow-Methods: указывает методы HTTP, разрешающие междоменные запросы, такие как: GET, POST, PUT, DELETE.
  • Access-Control-Allow-Headers: указывает, какую информацию заголовка разрешено передавать в запросе на доступ, например:Accept,Accept-Language,Content-Language,Content-Type

3. Четыре способа реализации CORS под SpringBoot

Представляет четыре способа реализации CORS, два из которых являются глобальной конфигурацией, а два — эффективной конфигурацией локального интерфейса. Вообще говоря, проекты SpringBoot могут реализовывать CORS одним из следующих способов.

3.1. Используйте CorsFilter для глобальной междоменной конфигурации

    @Configuration
    public class GlobalCorsConfig {
        @Bean
        public CorsFilter corsFilter() {
    
            CorsConfiguration config = new CorsConfiguration();
            //开放哪些ip、端口、域名的访问权限,星号表示开放所有域
            config.addAllowedOrigin("*");
            //是否允许发送Cookie信息
            config.setAllowCredentials(true);
            //开放哪些Http方法,允许跨域访问
            config.addAllowedMethod("GET","POST", "PUT", "DELETE");
            //允许HTTP请求中的携带哪些Header信息
            config.addAllowedHeader("*");
            //暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
            config.addExposedHeader("*");
    
            //添加映射路径,“/**”表示对所有的路径实行全局跨域访问权限的设置
            UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
            configSource.registerCorsConfiguration("/**", config);
    
            return new CorsFilter(configSource);
        }
    }


3.2. Перепишите метод addCorsMappings WebMvcConfigurer (глобальная междоменная конфигурация)

    @Configuration
    public class GlobalCorsConfig {
        @Bean
        public WebMvcConfigurer corsConfigurer() {
            return new WebMvcConfigurer() {
                @Override
                public void addCorsMappings(CorsRegistry registry) {
                    registry.addMapping("/**")    //添加映射路径,“/**”表示对所有的路径实行全局跨域访问权限的设置
                            .allowedOrigins("*")    //开放哪些ip、端口、域名的访问权限
                            .allowCredentials(true)  //是否允许发送Cookie信息 
                            .allowedMethods("GET","POST", "PUT", "DELETE")     //开放哪些Http方法,允许跨域访问
                            .allowedHeaders("*")     //允许HTTP请求中的携带哪些Header信息
                            .exposedHeaders("*");   //暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
                }
            };
        }
    }


3.3. Используйте аннотацию CrossOrigin (локальная междоменная конфигурация)

  • Добавьте аннотацию CrossOrigin к методу уровня Controller, конечная точка RequestMapping, определенная этим методом, будет поддерживать междоменный доступ.
  • Добавьте аннотацию CrossOrigin в определение класса уровня Controller, и конечные точки RequestMapping, соответствующие всем методам всего класса, будут поддерживать междоменный доступ.
    @RequestMapping("/cors")
    @ResponseBody
    @CrossOrigin(origins = "http://localhost:8080", maxAge = 3600) 
    public String cors( ){
        return "cors";
    }

3.4 Используйте HttpServletResponse для установки заголовков ответа (локальная междоменная конфигурация)

Этот метод немного проблематичен и не рекомендуется для использования в проектах SpringBoot.

    @RequestMapping("/cors")
    @ResponseBody
    public String cors(HttpServletResponse response){
        //使用HttpServletResponse定义HTTP请求头,最原始的方法也是最通用的方法
        response.addHeader("Access-Control-Allow-Origin", "http://localhost:8080");
        return "cors";
    }

В-четвертых, внедрение и тестирование

в SpringBootвне проектаПросто определите HTML и напишите код, чтобы вызвать следующий код ajax. (Я не буду писать процесс запуска, просто определяю кнопку и добавляю функцию прослушивания). Ниже приведен основной код для проверки междоменных запросов AJAX:

    $.ajax({
            url: 'http://localhost:8090/cors',
            type: "POST",
            xhrFields: {
               withCredentials: true    //允许发送Cookie信息
            },
            success: function (data) {
                alert("跨域请求配置成功")
            },
            error: function (data) {
                alert("跨域请求配置失败")
            }
        })

  • Успешная конфигурация междоменного запроса означает: наша междоменная конфигурация вступает в силу, и запрос ajax может корректно обращаться к интерфейсу сервера.
  • Сбой конфигурации междоменного запроса означает: наша междоменная конфигурация не вступает в силу, обратитесь к разделу 3, чтобы проверить правильность конфигурации.

Ждем вашего внимания