In-depth analysis of the principle of cross-site resource sharing CORS

I believe that if you have written a web application with separated front and back ends, or written some ajax request calls, you may have encountered CORS errors.

  • What is CORS?
  • Is it related to security?
  • Why should there be CORS? What purpose does it solve?
  • How does CORS work?

If you have these questions, then this article is for you.

1. What is CORS?

To understand what CORS (Cross-Origin Resource Sharing: cross-site resource sharing) is, we first need to understand what the Same Origin Policy Same Origin Policy(SOP) is. SOP is a security measure that all modern browsers have. It does not allow the Origin domain of loaded js scripts and resources to interact with another Origin domain. In other words, if your website is www.example.com, you cannot www.test.commake XHR requests to it.

So what is the use of SOP? If there is no restriction of the same-origin policy, what would happen if you think about it? For example: You have logged in to Weibo and accidentally opened a malicious website. This website can make a request to Weibo and extract personal information from your Weibo login session. This is obviously a huge security issue. In order to prevent this, the same-origin policy restriction is implemented in the browser. In fact, the server is not aware of all this happening on the browser side, you can still use curl or postman to make the same request, and everything responds normally, because there is no SOP on these tools.

If SOP is a way to restrict cross-origin access, then CORS is a way to bypass SOP restrictions and allow your front-end to make legitimate requests to the server. If your server does have a cross-domain situation (in fact, it is very common for modern distributed applications), your client will not be able to send xhr requests to multi-node cross-domain servers due to SOP restrictions. The saviour appeared. CORS enables us to make cross-domain requests in a safe and manageable way, breaking through the limitations of the same-origin policy.

2. Origin of Same Origin Policy (Origin of Same Origin Policy)

The source consists of three parts: protocol, hostip (domain) and port. E.g

  • http://example.com/xxx/index.htmlAnd http://example.com/yyy/index.htmlare homologous,
  • http://example.com:80And http://example.com(the default port for http is 80) is the same.
  • Since the protocols are different, http://example.com/app1and https://example.com/app2are different sources.
  • http://example.com, http://www.example.comBecause the domain name is different, it is also a different source
  • It’s important to note that http://localhostand http://127.0.0.1are different sources

The same-origin policy is that applications with different ip, port, and protocols are not allowed to share resources and request calls within the browser.

3. How does CORS work?

The CORS specification allows the server to return some HTTP headers to the browser, and the browser can decide whether to break the SOP restriction based on these HTTP headers. The most important HTTP Headers is Access-Control-Allow-Origin.

//目标服务允许所有的网站对其进行跨域访问
Access-Control-Allow-Origin: * 
//目标服务允许特定的网站对其进行跨域访问
Access-Control-Allow-Origin: https://example.com

CORS has two types of requests: "simple" simple requests and "preflight" preflight requests. Depending on the request method, the browser determines which request to use.

simple simple request:

If all of the following conditions are met, the API request is considered a simple request:

  • The API method is one of the following methods: GET, POST or HEAD.
  • Content-TypeRequest header application/x-www-form-urlencodedcomprising: multipart/form-data, ,text/plain

These two conditions will constitute most simple request use cases, but a more detailed list of simple request conditions can be found here .

If your API request is treated as a simplesimple request, this request can be sent directly to the server. The server responds with CORS HTTP Headers, and the browser will check Access-Control-Allow-Originto determine whether the request can break the limit of the same-origin policy and proceed to the next step.

preflight preflight request:

If your API request does not meet the criteria to be a simple request (the most common Content-Typevalue that does not meet the simple request criteria application/json), the browser will issue a preflight request before sending the actual request.

For example, we tried to use the GETrequest https://example.com/status, Content-Typeyes application/json, so the browser thinks it does not meet the standard of a simple request, so the browser will send a pre-check request before sending the actual request. This pre-check request is sent using the OPTIONS method of HTTP :

curl --location --request OPTIONS 'http://example.com/status' \
--header 'Access-Control-Request-Method: GET' \
--header 'Access-Control-Request-Headers: Content-Type, Accept' \
--header 'Origin: http://test.com'

The above curl is to simulate the preflight request. The actual effect is: the browser wants to tell the server that my actual request will GETbe called using HTTP method, Content-Typeand Acceptas HTTP headers, this request is https://test.cominitiated from. The server responds to this request:

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: OPTIONS, GET, HEAD, POST
Access-Control-Allow-Headers: Content-Type, Accept
  • Access-Control-Allow-Origin: The source that is allowed to make the request, or the request *can be made from any source. (Ie allow cross-domain sources)
  • Access-Control-Allow-Methods: A comma-separated list of allowed HTTP methods. (That is to allow cross-domain HTTP methods)
  • Access-Control-Allow-Headers: List of HTTP headers allowed to be sent.

After the browser receives the preflight request response *from the server, in our example, the server response can send a request from any source, so now the browser will visit again https://example.com/status, using the GET method (no longer OPTIONS method), the browser will no longer Restrict the sending of the request and the receiving of the response data. If the Origin of the preflight request response is specific Access-Control-Allow-Origin: http://domain.com, an Cross-Origin Request Blockederror will occur in the browser . Because the server-side pre-check results only allow http://domain.comcross-domain requests, other applications are not allowed to send cross-domain requests to me.

Four, how to deal with CORS errors

We now know what CORS is and how it works, the rest is actually simple. From the above content, we need to note that the full control of CORS is on the server, that is, the server can allow or prohibit cross-domain access to the source. Therefore, the processing of cross-domain issues is generally carried out on the server side. Different servers have different codes for processing HTTP request headers. Of course, it is not necessary to write code, such as nginx, haproxy settings. But the same is true: the HTTP headers are ultimately rewritten .

Let me give a few simple examples:

For example, Servlet handles cross-domain

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) resp; 
        response.setHeader("Access-Control-Allow-Origin", "*"); //解决跨域访问报错   
        response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");   
        chain.doFilter(req, resp); 
}

Such as Spring MVC configuration

@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("*");   //暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
            }
        };
    }
}

Welcome to follow my blog, there are many boutique collections

  • This article is reproduced indicate the source (en must not turn only the text): letters Gebo off .

If you think it is helpful to you, please like and share it for me! Your support is my inexhaustible creative motivation! . In addition, the author has output the following high-quality content recently, and I look forward to your attention.

Guess you like

Origin blog.csdn.net/hanxiaotongtong/article/details/109282415