Three ways SpringBoot:CORS handles cross-domain requests

Posted by Fredix on Tue, 17 Sep 2019 03:44:53 +0200

1. Cross-domain Background

1.1 What is cross-domain?

General format of Url:

Protocol + Domain Name (Subdomain + Primary Domain Name) + Port Number + Resource Address

Example:

https://www.dustyblog.cn:8080/say/Hello is created by

https + www + dustyblog.cn + 8080 + say/Hello Form

 

Form.

As long as one of the four components, protocol, subdomain name, primary domain name, and port number, is different, it can be considered a different domain. Different domains access each other's resources and are called cross-domain.

1.2 Normal requests

  • Controller layer code:
1 @RequestMapping("/demo")
2 @RestController
3 public class CorsTestController {
4 
5     @GetMapping("/sayHello")
6     public String sayHello() {
7         return "hello world !";
8     }
9 }
  • Start the project, test the request

Browser Open localhost:8080/demo/sayHello

Print out "hello world"

1.3 Cross-domain Testing

Take Chrome for example:

  • Open any website, such as: https://blog.csdn.net

  • Press F12, open Developer Tools, where Console can enter js code tests directly;

var token= "LtSFVqKxvpS1nPARxS2lpUs2Q2IpGstidMrS8zMhNV3rT7RKnhLN6d2FFirkVEzVIeexgEHgI/PtnynGqjZlyGkJa4+zYIXxtDMoK/N+AB6wtsskYXereH3AR8kWErwIRvx+UOFveH3dgmdw1347SYjbL/ilGKX5xkoZCbfb1f0=,LZkg22zbNsUoHAgAUapeBn541X5OHUK7rLVNHsHWDM/BA4DCIP1f/3Bnu4GAElQU6cds/0fg9Li5cSPHe8pyhr1Ii/TNcUYxqHMf9bHyD6ugwOFTfvlmtp6RDopVrpG24RSjJbWy2kUOOjjk5uv6FUTmbrSTVoBEzAXYKZMM2m4=,R4QeD2psvrTr8tkBTjnnfUBw+YR4di+GToGjWYeR7qZk9hldUVLlZUsEEPWjtBpz+UURVmplIn5WM9Ge29ft5aS4oKDdPlIH8kWNIs9Y3r9TgH3MnSUTGrgayaNniY9Ji5wNZiZ9cE2CFzlxoyuZxOcSVfOxUw70ty0ukLVM/78=";
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1:8080/demo/sayHello');
xhr.setRequestHeader("x-access-token",token);
xhr.send(null);
xhr.onload = function(e) {
    var xhr = e.target;
    console.log(xhr.responseText);
}

The results indicate that the request failed under the domain name https://blog.csdn.net!

2. Solution - Cors Cross-Domain

What is 2.1 Cors

CORS is fully known as Cross Origin Resource Sharing. Each page needs to return an http header named Access-Control-Allow-Origin to allow site access in foreign countries. You can only expose limited resources and limited site access in foreign countries.

We can understand that if a request needs to allow cross-domain access, it needs to be set in the http header

Access-Control-Allow-Origin To determine which sites you need to allow.If hypothesis requires permission https://www.dustyblog.c This site has cross-domain requests, you can set:

Access-Control-Allow-Origin:https://www.dustyblog.cn. 

2.2 How to Solve Cors Cross-Domain

Scenario 1 of 2.2.1: Using the @CrossOrigin annotation

Using the @CrossOrigin annotation on Controller, all interfaces under this class are accessible across domains

 1 @RequestMapping("/demo2")
 2 @RestController
 3 //@CrossOrigin //All domain names have access to all interfaces under this class
 4 @CrossOrigin("https://blog.csdn.net") // Only the specified domain name can access all interfaces under this class
 5 public class CorsTest2Controller {
 6 
 7     @GetMapping("/sayHello")
 8     public String sayHello() {
 9         return "hello world --- 2";
10     }
11 }

This specifies that all methods in the current CorsTest2Controller can handle requests on the https://csdn.net domain. Here you can test:

  • stay https://blog.csdn.net The page opens the debugging window and enters (Note: Request address here is / demo2, please distinguish from / demo in 1.2 cases)
var token= "LtSFVqKxvpS1nPARxS2lpUs2Q2IpGstidMrS8zMhNV3rT7RKnhLN6d2FFirkVEzVIeexgEHgI/PtnynGqjZlyGkJa4+zYIXxtDMoK/N+AB6wtsskYXereH3AR8kWErwIRvx+UOFveH3dgmdw1347SYjbL/ilGKX5xkoZCbfb1f0=,LZkg22zbNsUoHAgAUapeBn541X5OHUK7rLVNHsHWDM/BA4DCIP1f/3Bnu4GAElQU6cds/0fg9Li5cSPHe8pyhr1Ii/TNcUYxqHMf9bHyD6ugwOFTfvlmtp6RDopVrpG24RSjJbWy2kUOOjjk5uv6FUTmbrSTVoBEzAXYKZMM2m4=,R4QeD2psvrTr8tkBTjnnfUBw+YR4di+GToGjWYeR7qZk9hldUVLlZUsEEPWjtBpz+UURVmplIn5WM9Ge29ft5aS4oKDdPlIH8kWNIs9Y3r9TgH3MnSUTGrgayaNniY9Ji5wNZiZ9cE2CFzlxoyuZxOcSVfOxUw70ty0ukLVM/78=";
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1:8080/demo2/sayHello');
xhr.setRequestHeader("x-access-token",token);
xhr.send(null);
xhr.onload = function(e) {
    var xhr = e.target;
    console.log(xhr.responseText);
}

Return results:

ƒ (e) {
    var xhr = e.target;
    console.log(xhr.responseText);
}
VM156:8 hello world --- 2

Indicates cross-domain success!

  • Change the domain name to test if cross-domain is still valid. In https://www.baidu.com Test as described above and return the results:
OPTIONS http://127.0.0.1:8080/demo2/sayHello 403
(anonymous)
Access to XMLHttpRequest at 'http://127.0.0.1:8080/demo2/sayHello' 
from origin 'http://www.cnblogs.com' has been blocked by CORS policy: 
Response to preflight request doesn't pass access control check: 
No 'Access-Control-Allow-Origin' header is present on the requested resource.

Explain cross-domain failure!Prove that this scheme successfully specifies some domain names that can cross domains!

2.2.2 Scenario 2: CORS Global Configuration - Implementing WebMvcConfigurer

  • New cross-domain configuration class: CorsConfig.java:
 1 /**
 2  * Cross-domain Configuration
 3  */
 4 @Configuration
 5 public class CorsConfig implements WebMvcConfigurer {
 6 
 7     @Bean
 8     public WebMvcConfigurer corsConfigurer()
 9     {
10         return new WebMvcConfigurer() {
11             @Override
12             public void addCorsMappings(CorsRegistry registry) {
13                 registry.addMapping("/**").
14                         allowedOrigins("https://www.dustyblog.cn"). //Allow cross-domain domain domain names, which can be used*Indicates that any domain name is allowed
15                         allowedMethods("*"). //Allow any method ( post,get Etc.)
16                         allowedHeaders("*"). //Allow any request header
17                         allowCredentials(true). //close cookie information
18                         exposedHeaders(HttpHeaders.SET_COOKIE).maxAge(3600L); //maxAge(3600)Indicates that within 3600 seconds, no further pre-validation requests need to be sent, and the results can be cached
19             }
20         };
21     }
22 }
  • Test the domain name that is allowed to access https://www.dustyblog.cn/ Console input (note that http://127.0.0.1:8080/demo3 is requested here):
var token= "LtSFVqKxvpS1nPARxS2lpUs2Q2IpGstidMrS8zMhNV3rT7RKnhLN6d2FFirkVEzVIeexgEHgI/PtnynGqjZlyGkJa4+zYIXxtDMoK/N+AB6wtsskYXereH3AR8kWErwIRvx+UOFveH3dgmdw1347SYjbL/ilGKX5xkoZCbfb1f0=,LZkg22zbNsUoHAgAUapeBn541X5OHUK7rLVNHsHWDM/BA4DCIP1f/3Bnu4GAElQU6cds/0fg9Li5cSPHe8pyhr1Ii/TNcUYxqHMf9bHyD6ugwOFTfvlmtp6RDopVrpG24RSjJbWy2kUOOjjk5uv6FUTmbrSTVoBEzAXYKZMM2m4=,R4QeD2psvrTr8tkBTjnnfUBw+YR4di+GToGjWYeR7qZk9hldUVLlZUsEEPWjtBpz+UURVmplIn5WM9Ge29ft5aS4oKDdPlIH8kWNIs9Y3r9TgH3MnSUTGrgayaNniY9Ji5wNZiZ9cE2CFzlxoyuZxOcSVfOxUw70ty0ukLVM/78=";
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1:8080/demo3/sayHello');
xhr.setRequestHeader("x-access-token",token);
xhr.send(null);
xhr.onload = function(e) {
    var xhr = e.target;
    console.log(xhr.responseText);
}

Return results:

ƒ (e) {
    var xhr = e.target;
    console.log(xhr.responseText);
}
VM433:8 hello world --- 3

Explain cross-domain success with a different web address such as https://www.baidu.com The test still had error prompts requiring cross-domain validation that the configuration was correct and the scenario test passed.

2.2.3 Scheme 3: Interceptor Filter Implementation

Solve cross-domain issues by implementing the Fiter interface and adding headers to requests

 1 @Component
 2 public class CorsFilter implements Filter {
 3 
 4     @Override
 5     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
 6             throws IOException, ServletException {
 7         HttpServletResponse res = (HttpServletResponse) response;
 8         res.addHeader("Access-Control-Allow-Credentials", "true");
 9         res.addHeader("Access-Control-Allow-Origin", "*");
10         res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
11         res.addHeader("Access-Control-Allow-Headers", "Content-Type,X-CAF-Authorization-Token,sessionToken,X-TOKEN");
12         if (((HttpServletRequest) request).getMethod().equals("OPTIONS")) {
13             response.getWriter().println("ok");
14             return;
15         }
16         chain.doFilter(request, response);
17     }
18     @Override
19     public void destroy() {
20     }
21     @Override
22     public void init(FilterConfig filterConfig) throws ServletException {
23     }
24 }

So far, the cross-domain request is complete, and friends with more and better ways are welcome to leave a message!

Good Text to Learn From: https://www.cnblogs.com/vandusty/p/11408422.html

Topics: Java