Today, LET’s talk about how to solve cross-domain problems through CORS.

The same-origin policy

A lot of people have a misconception that cross-domain is about the front end, not the back end, but actually it’s not. When it comes to cross-domain, we have to talk about the same origin policy of the browser.

The same origin policy is a famous security policy proposed by Netscape. It is the core and most basic security feature of the browser. Now all browsers that support JavaScript use this policy. The same protocol, domain name, and port must be the same. The same origin policy is proposed based on security considerations, which is no problem in itself, but in actual development, due to various reasons, we often have cross-domain requirements. The traditional cross-domain solution is JSONP. Although JSONP can solve cross-domain, it has a great limitation, that is, it only supports GET requests. CORS (Cross-Origin Resource Sharing) is a W3C standard. It is a specification of browser technology that provides a way for Web services to transmit sandbox scripts from different domains. To avoid the browser’s same-origin policy, which is a modern version of the JSONP pattern.

The Spring framework also provides a solution for CORS, so today we’ll look at how to implement CORS in SpringBoot.

practice

Let’s take a look at how to implement this in Spring Boot.

Create two normal Spring Boot projects. The first one is named Provider to provide the service, the second one is named Consumer to consume the service, the first configuration port is 8080, and the second configuration configuration is 8081. The provider then provides two Hello interfaces, one get and one POST, as follows:

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello(a) {
        return "hello";
    }
    @PostMapping("/hello")
    public String hello2(a) {
        return "post hello"; }}Copy the code

Create an HTML file in the Consumer’s Resources /static directory and send a simple Ajax request as follows:

<div id="app"></div>
<input type="button" onclick="btnClick()" value="get_button">
<input type="button" onclick="btnClick2()" value="post_button">
<script>
    function btnClick() {
        $.get('http://localhost:8080/hello'.function (msg) {$("#app").html(msg);
        });
    }

    function btnClick2() {
        $.post('http://localhost:8080/hello'.function (msg) {$("#app").html(msg);
        });
    }
</script>
Copy the code

Then launch the two projects separately, send the request button, and observe the browser console as follows:

Access to XMLHttpRequest at 'http://localhost:8080/hello' from origin 'http://localhost:8081' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Copy the code

As you can see, the request could not be sent due to the same origin policy.

Using CORS allows cross-domain implementation without any changes to the front-end code, so let’s look at how to configure it in a provider. You can first configure a method to accept requests for a field using the @Crossorigin annotation as follows:

@RestController
public class HelloController {
    @CrossOrigin(value = "http://localhost:8081")
    @GetMapping("/hello")
    public String hello(a) {
        return "hello";
    }

    @CrossOrigin(value = "http://localhost:8081")
    @PostMapping("/hello")
    public String hello2(a) {
        return "post hello"; }}Copy the code

This annotation indicates that the two interfaces accept requests from http://localhost:8081, and when configured, restart the provider and send the request again, so that the browser console does not report an error and the consumer can get the data.

If you look at the browser request network console, you can see the following information in the response header:

This indicates that the server is willing to accept the request from http://localhost:8081. With this information, the browser does not restrict the cross-domain of the request.

In Spring Boot, you can also use global configuration to solve this problem at once. In Spring Boot, you can use global configuration to solve this problem. The global configuration simply requires overriding the addCorsMappings method in the SpringMVC configuration class, as follows:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/ * *")
        .allowedOrigins("http://localhost:8081")
        .allowedMethods("*")
        .allowedHeaders("*"); }}Copy the code

/** indicates that all methods of the application process cross-domain requests, allowedMethods indicates the number of requests that are allowed to pass, and allowedHeaders indicates the allowed request headers. After this configuration, it is not necessary to configure cross-domains separately on each method.

Existing problems

After understanding the whole working process of CORS, we send cross-domain request through Ajax. Although the user experience is improved, there are also potential threats, the common one is CROSS-site Request Forgery (CSRF). Cross-site request forgery, also known as one-click attack or Session riding, commonly abbreviated CSRF or XSRF, is an attack that forces a user to perform unintentional actions on a currently logged Web application. For example:

If a bank uses the following URL to run money transfers: http://icbc.com/aa?bb=cc, a malicious attacker could place the following code on another website: if a user visits a malicious site and her login information has not expired after a recent visit to the bank, she will suffer a loss.

Based on this, the browser will classify the request in actual operation, including simple request, pre-request, request with credentials, etc. Pre-request will first send an Options detection request, and negotiate with the browser whether to accept the request. By default, cross-domain requests do not require credentials, but the server can be configured to require credentials from the client, thus effectively avoiding CSRF attacks.

Ok, so much for this question, songko also has a little video tutorial on Spring Boot CORS

  • Spring Boot uses CORS to solve cross-domain problems

Pay attention to the public account [Jiangnan little Rain], focus on Spring Boot+ micro service and front and back end separation and other full stack technology, regular video tutorial sharing, after attention to reply to Java, get Songko for you carefully prepared Java dry goods!