What you should know about CORS
By Nicolas Bailly
Translator: Boxuan
If you’re like me, the first timeCORS(cross domain resource sharing), you want the server to receive those you splicedAjax
Request and process them. So you go to stackoverflow.com and copy a piece of code to set up some HTTP headers so that the request can work normally.
But there may be other things you should know.
What is CORS, not what
The reason novices are often confused is because they are not clearCORSWhat can be done. First,CORSIt’s not a security measure, it’s actually the opposite:CORSIt’s a way to bypass the same origin strategy (SOP). The same origin policy is a security measure that prevents you from issuing to other domainsAjax
Request.
The same origin policy declares a web site on one domain and cannot issue an XMLHttpRequest (XHR) request to another domain. This prevents malicious websites from making requests to known websites, such as Facebook or Google, to change the user’s login status so that they can impersonate other users. This policy is implemented by browsers (all browsers implement the same origin policy, although there are subtle differences in implementation details), which means that this policy is not applicable to requests from servers or any other HTTP clients (such as curl, postman). In addition, the server also has no full control over it: the server will process each request and assume that they are from a trusted domain, and whether the request will be blocked depends entirely on the browser.
Homologous strategyIn no way does it prevent an attacker from making requests to your server (because it is clear that the attacker will not use the browser). It’s just to prevent legitimate users from making requests to your website without their knowledge when browsing the website with a well-known browser.
CORSIt’s a way to bypass the same origin policy. In some cases, you want some special sites to make requests to your server, even if it’s normally blocked. Typically, it allows your front-end application to make requests to your API.
How CORS works
AndHTTPThe same.CORSIt’s basically a conversation between the browser and the server. Suppose your front-end domain name isdomain-a.com
, the domain name of the backend API isdomain-b.com
, the conversation will be like this:
-
Browser:“Hey
domain-b.com
,domain-a.com
The script on will launch to you onceAjax
Please, but I should stop it, unless you tell me it’s OK. “ -
The serverI don’t know, but I can tell you,
https://domain-a.com
Only get, post, options and delete requests are allowed to be sent and need to be verified every 10 minutes. “
BrowserThink about it: “Yeah, this is the right domain name. I should send him a request.”
-
Browser:“Hey
domain-b.com
I want to send you a post request at this terminal. “ -
The server“No problem, this is yours
200
”
Or, if the user is in a different domain, the conversation is shorter:
-
Browser:“Hey
domain-b.com
,malicious-domain.com
This script on (malicious site) will launch to you onceAjax
Please, but I should stop it, unless you tell me it’s OK. “ -
The serverI don’t know, but I can tell you,
https://domain-a.com
Only get, post, options and delete requests are allowed to be sent and need to be verified every 10 minutes. “
BrowserThink about it: “Oh, this is not the right domain name, we’d better not send the request”, and then print the error in the console.
Note: second, when you use the developer tool to view, you cannot see the response headers, but you can see the prompt in the following figure:
Node CORS test address
What it looks like in a browser
In the above scenario, the first question raised by the browser is called the pre check request, and the corresponding HTTP predicate isOPTIONS
。 In case of such a pre check request, the server should always return a 200 response with no body, but it will containAccess-Control-Allow-Origin
, and some other response headers. In our example, the response header is as follows:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://domain-a.com
Access-Control-Allow-Methods: GET, POST, OPTIONS, DELETE
Access-Control-Max-Age: 3600
It tells the browser that it can only respond to requests fromdomain-a.com
It can process get, post, options or delete requests (put requests will be blocked), and it can cache this information for 3600 seconds, so it does not need to initiate a newOPTIONS
Request.
Of course, it won’t work if we use other domains. Browser will sendOPTIONS
Request, then throw an exception in the console, and never send itPOST
Request.
It’s direct, isn’t it?
But there are some pitfalls
On the knotty problems of CORS
All requests contain CORS headers(headers
)
You may think that if your server respondsOPTIONS
200 on request, and then you remove the correct response headers. And then you’ll see that the browser sent it firstOPTIONS
Request, and then sent other requests, other requests hung up… This is because each request (get, post, or other request) should contain the same response header: “access control allow headers”.
Not all requests trigger a pre check request
Some requests do not trigger a pre check request, such as a get request, orContent-Type
Set toapplication/x-www-form-urlencoded
Post request for. These are the “simple requests” that browsers always allow (even if CORS doesn’t support them, you can still use hyperlinks(a
Tag) or use post to request forms to other sites, where you can find the full list. In the case of a post request, the result is a bit counterintuitive: the browser will make a post request (so your server may keep some data), and then ignore the response.
In traditional web applications, you can use theapplication/json
Act ascontent-type
, so there will be pre check requests, but remember that your server may still receive post requests from other domains, so don’t blindly accept them.
The allowed domain name must contain a protocol
You can’t justmydomain.com
As a domain name, it also needs to contain protocols (for example:https://mydomain.com
) Interestingly, you can’t receive it at the same timehttp
andhttps
Because
You can only allow one domain
You can use theAccess-Control-Allow-Origin: *
To allow each domain access, or only one domain access. This means that if you need more than one domain to access yourAPI
When, you need to deal with it yourself.
The easiest way to deal with this problem is to maintain the list of domains allowed to access on the server. If the domain is in the list, the content of the response header will be changed dynamically. Here is an example of PHP:
$allowedDomains = [
"http://www.mydomain.com",
"https://www.mydomain.com",
"http://www.myotherdomain.com",
"http://www.myotherdomain.com",
];
$originDomain = $_SERVER['HTTP_ORIGIN'];
if (in_array($originDomain, $allowedDomains)) {
header("Access-Control-Allow-Origin: $originDomain");
};
Or the example of node.js (adapted from the stackoverflow answer)
app.use(function(req, res, next) {
const allowedOrigins = [
"http://www.mydomain.com",
"https://www.mydomain.com",
"http://www.myotherdomain.com",
"http://www.myotherdomain.com",
];
const origin = req.headers.origin;
if(allowedOrigins.indexOf(origin) > -1){
res.setHeader('Access-Control-Allow-Origin', origin);
}
return next();
});
The same origin policy is applicable to the file systems of chrome and safari, not Firefox
If you make a request to a local file, Firefox assumes that it is always on the same domain and allows the request. Be based onWebkit‘s browser, such as chrome or Safari, treats this as a security risk and blocksAjax
Query. The only way to solve this problem is to use Firefox, or install will sendAccess-Control-Allow-Origin: *
Web server for the response header.
As @ Brian Jenkins 94 points out in the comments, you can also use the--disable-web-security
Parameter to start chrome.
IOS wkwebview requires CORS
If you are developing and usingwebview
Android (using Cordova or ionic) mobile app will not cause you any trouble, but new on IOSWKWebview
CORS will be required. This means that you almost always have toAccess-Control-Allow-Origin
Header set to*
But it’s not ideal.
Another option is not to issue in your applicationAjax
Request and usecordova
Plug in cost machinehttp
Request, which will easily bypass the same origin policy.
Thank you for reading!
If you want to learn more about CORS, visit MDN:
https://developer.mozilla.org…
The author of this article has been contacted and authorized to translate. Please keep the original link for reprint