This is the 24th day of my participation in the August Text Challenge.More challenges in August

This article will not systematically explain the principle of cross-domain, focusing on how SpringBoot can best solve cross-domain problems, but will simply talk about the concept of cross-domain.

Cause of cross-domain

The same origin policy is restricted by the browser. The Sameoriginpolicy is a convention. It is the core and basic security function of the browser. If the Sameoriginpolicy is missing, the normal functions of the browser may be affected. The Web is built on the same origin policy, and browsers are just an implementation of the same origin policy. The same origin policy prevents javascript scripts in one domain from interacting with content in another domain. Same-origin (that is, in the same domain) means that two pages have the same protocol, host, and port.

Best practices across domains

In a production environment, it is best to address cross-domain issues from the server side of the portal, such as through Nginx or API gateways, so that each of our microservices does not need to address cross-domain issues. Because if you resolve multiple times across domains, there will be errors. The client cannot be accessed. Since cross-domain problems should be solved by the request entry, does our SpringBoot project need to solve cross-domain problems? The answer to that is, because in the daily alignment, we are likely to use their own machine alignment, the client direct call, can’t micro service gateway And we as micro service provides the ability to solve the cross domain, and the switch selection in the form of cross-domain, so even if the API gateway not solve the cross domain, the client can also visit our micro service correctly.

SpringBoot addresses cross-domain

SpringBoot provides the CorsFilter utility class. We can solve the cross-domain problem by configuring CorsConfiguration.

  1. One of the roughest cross-domain configurations

All use the default cross-domain configuration. The default cross-domain configuration means that all requests will be accepted and no requests will cross the domain. However, this is risky behavior and should be used with caution in reproduction environments.

    @Bean
    public CorsFilter corsFilter(a) {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/ * *", corsConfiguration);
        return new CorsFilter(urlBasedCorsConfigurationSource);
    }
Copy the code
  1. Custom resolve cross-domain by manually passing in cross-domain configuration rules

For example, only GET and POST requests are allowed, and only the token option is allowed in the header. Otherwise, the request will cross domains. In this scenario, the following configuration can be used

    @Bean
    public CorsFilter corsFilter(a) {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        
        corsConfiguration.setAllowedHeaders(Collections.singletonList("token"));
        corsConfiguration.setAllowedMethods(Arrays.asList("GET"."POST"));
        
        UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/ * *", corsConfiguration);
        return new CorsFilter(urlBasedCorsConfigurationSource);
    }
Copy the code
  1. Resolve SpringBoot configuration files to avoid hard coding problems

We can use the capability of SpringBoot’s configuration file to configure cross-domain information into the configuration file, avoiding the hard coding of the program, and make use of Spring’s ConditionalOnProperty to install the switch for cross-domain configuration so that it can be flexible for different scenarios. And this form can be completely self-contained by automatic/manual assembly of SpringBoot into a separate component

3.1 Cross-domain Configuration Classes

     @Data
     @Component
     @ConfigurationProperties(prefix = "example.web.cors")
     public class CorsProperties {
     /** * Whether to enable cross-domain resolution */
     private Boolean enable;
     /** * allowedOrigins default is ** /
     private List<String> allowedOrigins;
     {GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE} */
     private List<String> allowedMethods;
     /** * allowedHeaders is ** / by default
     private List<String> allowedHeaders;
     /** * exposedHeaders default is ** /
     private List<String> exposedHeaders;
     /** * allowCredentials default to true */
     private Boolean allowCredentials = true;
     /** * maxAge */
     private Long maxAge;
     
     }
Copy the code

3.2 Constructing cross-domain Objects through configuration

 @Bean
 @ConditionalOnProperty( prefix = "example.web.cors", name = {"enable"}, havingValue = "true" )
 @ConditionalOnMissingBean(value = CorsFilter.class)
 public CorsFilter corsFilter(CorsProperties corsProperties) {
     log.info("\ncors enabled.");
     CorsConfiguration corsConfiguration = generatorCorsConfiguration(corsProperties);
     final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
     urlBasedCorsConfigurationSource.registerCorsConfiguration("/ * *", corsConfiguration);
     return new CorsFilter(urlBasedCorsConfigurationSource);
 }

 /** * If not, use the default solution */
 private CorsConfiguration generatorCorsConfiguration(CorsProperties corsProperties) {

     final CorsConfiguration corsConfiguration = new CorsConfiguration();

     List<String> allowedOrigins = corsProperties.getAllowedOrigins();
     if (Objects.isNull(allowedOrigins)) {
         corsConfiguration.addAllowedOrigin(CorsConfiguration.ALL);
     } else {
         corsConfiguration.setAllowedOrigins(allowedOrigins);
     }

     List<String> allowedHeaders = corsProperties.getAllowedHeaders();
     if (Objects.isNull(allowedHeaders)) {
         corsConfiguration.addAllowedHeader(CorsConfiguration.ALL);
     } else {
         corsConfiguration.setAllowedHeaders(allowedHeaders);
     }

     List<String> allowedMethods = corsProperties.getAllowedMethods();
     if (Objects.isNull(allowedMethods)) {
         corsConfiguration.addAllowedMethod(CorsConfiguration.ALL);
     } else {
         corsConfiguration.setAllowedMethods(allowedMethods);
     }

     Boolean allowCredentials = corsProperties.getAllowCredentials();
     corsConfiguration.setAllowCredentials(allowCredentials);
     corsConfiguration.setMaxAge(corsProperties.getMaxAge());
     return corsConfiguration;
 }
Copy the code

3.3 Configuration File Demonstration

example:
   web:
     cors:
      # Cross-domain switch
      enable: true
       allowed-headers:
       - token
       allowed-methods:
       - GET
       - POST
Copy the code