How to deal with cookies when cross-domain?

foreword

From sending to returning a request requires the coordination of the browser and the server. The browser needs to bring its own request parameters to the server. After the server verifies the parameters, in addition to returning data, it may also tell the browser whether the request is cached, cookies and other information. When the request is a cross-origin request, the process is even more complicated. Next, let's take a look at what problems will arise across domains, and what kind of cooperation is required between the front and back ends.

common domain

I have a friend named Xiao Wang. The front-end Xiao Wang and the back-end colleague Xiao Ma are going to jointly debug a login API. Suppose it is /login; Xiao Wang happily initiated the post submission after preparing the login account and password. The result was unexpected, the response to the request was intercepted by the browser, and the browser thoughtfully threw an error on the console.
preview
Xiao Wang translated it, and it turned out that it was blocked by the CORS strategy. This strategy roughly means that if the server allows requests from different origins, it needs to include the Access-Control-Allow-Origin header in the returned response header. Otherwise, when the browser gets the response and finds that there is no such header in the response header, it will swallow the response instead of handing it over to js for further processing.

Xiao Wang told Xiao Ma about this, and Xiao Ma added in the returned header

Access-Control-Allow-Origin: *

Now Xiao Wang can finally get the returned result.

It should be noted here that the browser does not intercept the request at the request stage, but sends the request normally. After getting the response from the server, it starts to check whether there is an Access-Control-Allow-Origin header in the response header. If not, respond The result will not go to js.

Cross-domain non-simple requests

Later, Xiao Wang felt that it was too troublesome to send the body in the form format in the post, and hoped to submit the request body in JSON format. Xiao Ma felt that it was just a few lines of code, so he agreed. But after Xiao Wang changed the message body to JSON, he found that it was intercepted by CORS again, and the following error was thrown:
preview

In the above error report, we saw the word preflight. So what's going on here? It turns out that after modifying the request body, this cross-domain request is no longer a simple request, and a preflight request needs to be made before the request is initiated. So what is a simple request?

  • Request methods include GET, HEAD, POST
  • The response header cannot contain headers other than the CORS security header.
  • Content-Type is limited to text/plain, multipart/form-data, application/x-www-form-urlencoded

Due to the content-type of json data, this post request is no longer a simple request, and for non-simple requests, cross-domain access for all domain names was previously prohibited. So it is still necessary to modify Access
Control-Allow-Origin to a specific request domain name. In development mode, it might be - http://localhost:3000 or something.

Xiao Ma is re-modifying Access-Control-Allow-Origin, and Xiao Wang gets the result of successful login again. You can jointly debug the next API.

Cross-domain with cookies

The login is based on the session, that is to say, after the login is successful, the server will set the cookie to the browser through set-cookie, so that the next time you visit the API under the same source, the cookie will be brought.

However, the strange thing is that Xiao Wang found that after he successfully logged in, he called another interface, but the cookie was not carried, which caused the server to fail to recognize the user information, and finally returned an error (status code 401).

withCredentials

It turns out that when a browser initiates a cross-domain request, it will not take the initiative to bring cookies. If a request requires a cookie, the developer needs to set an option. Take fetch api as an example:

fetch('http://baidu.com:3000', {
    
    
    // ...
	credentials: 'include'
})

If you use xhr api to request, you need to write like this:

var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/credentialed-content/';

function callOtherDomain(){
    
    
  if(invocation) {
    
    
    invocation.open('GET', url, true);
    invocation.withCredentials = true; // 带上cookie
    invocation.onreadystatechange = handler;
    invocation.send();
  }
}

Xiao Wang made another request after setting the request. But I found that the cookie was still not brought up. Xiao Wang had no choice but to continue to check the information on MDN, and found that a sameSite attribute needs to be included when setting-cookie.

sameSite

sameSite is an attribute generated to prevent csrf attacks. If you don't know what a CSRF attack is, you can check it yourself first.

Since we need to bring a cookie in the request, we need to set the sameSite of the cookie to none when setting-cookie; and because we also need to set Secure when setting the sameSite to none, the request needs to be based on https;

The last time Xiao Wang asked Xiao Ma to appeal and change the API, the server finally recognized who the request came from and returned the correct result.

Summarize

Many times, we may only pay attention to what the request body is, whether the response is returned correctly, and ignore the header part. As everyone knows, headers play an important role in caching, web security, and correct parsing results by browsers, such as a series of Access-Control-Allow-* headers in this article.

In order to make the web more secure, CORS is constantly being updated. For example, this proposal stipulates that when accessing a local network from a public network or from a private network, a cross-domain header, Access-Control-Allow-Private-Network, needs to be set.

Guess you like

Origin blog.csdn.net/hyqhyqhyqq/article/details/130618876