CORS
Overview
Modern web browsers apply the Same-Origin Policy to prevent information held by one website from being abused by another malicious website.
For example, when a frontend communicates with a backend API on a different domain and requests resources, an error occurs because the Origin, meaning domain, protocol, and port number, is different. If a page at https://api.devkuma.com/ tries to read data over HTTP(S) from another website, https://www.devkuma.com/, using XMLHttpRequest (XHR) or the Fetch API, an error occurs.
However, if even trusted websites used for data integration are blocked, it becomes inconvenient. CORS (Cross-Origin Resource Sharing) is needed so that websites allowed to access data can do so even when the Origin is different.
What Is CORS?
- CORS stands for Cross-Origin Resource Sharing and means resource sharing between origins.
- Browsers generally prohibit communication between different origins, but CORS settings allow communication between different origins.
- It is a method that permits data to be received from a domain different from the page being viewed in the browser.
- It is used by browsers to prevent cross-site scripting for security.
- There is a restriction that communication can only occur with the origin domain’s server.
What Is Origin?
To understand CORS more precisely, you need to understand origin. The origin of web content is defined by the URL scheme (protocol), host (domain), and port used to access that content. Two objects are considered to have the same origin only when all three match.
On the web, work is limited to same-origin content by the Same-Origin Policy, and this restriction can be relaxed using CORS.
Same Origin Examples
The scheme (http) and host (www.devkuma.com) are the same, so they are the same origin.
http://www.devkuma.com/app1/index.html
http://www.devkuma.com/app2/index.html
The server uses the default port 80 and serves HTTP content, so it is the same origin.
http://www.devkuma.com:80
http://www.Devkuma.com
Different Origin Examples
Different scheme:
http://devkuma.com/app1
https://devkuma.com/app2
Different host:
http://devkuma.com
http://www.devkuma.com
http://blog.example.com
Different port:
http://www.devkuma.com
http://www.devkuma.com:8080
Why Is CORS Necessary?
Browsers adopt the same-origin policy for security reasons. It is used to prevent other origins from freely accessing your resources.
If a site you do not operate can obtain session requests, that site may hijack your session and perform malicious actions. Therefore, browsers block these requests.
Phishing sites are a representative attack example, and CORS is needed to stop such attacks and allow requests only from origins that you have permitted.
How CORS Works
When the browser requests a resource, it includes additional information in headers: what the origin is, which method will be used, and which headers will be included. The server sends back the origins it can respond to in response headers. The browser checks these headers and allows the resource transfer if the request is allowed from that origin; otherwise, it raises an error.
CORS Preflight Request
This is a system composed of HTTP header exchanges. The browser determines whether frontend JavaScript code may access the response to a cross-origin request.
Request Headers
Origin: shows which origin is accessing.Access-Control-Request-Method: tells the server which method will be used in the actual request during a preflight request.Access-Control-Request-Headers: tells the server which headers will be used in the actual request during a preflight request.
Response Headers
Access-Control-Allow-Origin: allows the browser to access the resource from that origin.*allows access from all origins only for requests without credentials.Access-Control-Expose-Headers: lists which headers may be exposed as part of the response.Access-Control-Max-Age: indicates how long preflight request results can be cached.Access-Control-Allow-Credentials: indicates whether the response to a request can be exposed when credentials are true.Access-Control-Allow-Methods: indicates methods allowed in response to a preflight request.Access-Control-Allow-Headers: indicates HTTP headers that can be used in the actual request.
CORS Examples
The examples describe allowing HTTP(S) access from https://www.devkuma.com to https://api.devkuma.com.
Allowing Simple Data Loading
To allow GET and POST from XHR or Fetch API, the client declares CORS for Fetch, and the server adds appropriate information to the HTTP response headers.
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.devkuma.com');
xhr.addEventListener('load', onLoadFunc, false);
xhr.send(null);
fetch('https://api.devkuma.com', {
mode: 'cors'
}).then(onLoadFunc);
GET /api HTTP/1.1
Origin: https://www.devkuma.com
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://www.devkuma.com
For simple cases, a wildcard can be used.
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Allowing Cookies
To allow cookies to be sent and received during HTTP(S) communication, both the browser and server need configuration. In this case, wildcard values are not allowed for Access-Control-Allow-Origin.
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://www.devkuma.com
Access-Control-Allow-Credentials: true
Using Detailed HTTP Communication
If the request method is not GET, POST, or HEAD, or if special request headers or content types are used, CORS performs an OPTIONS preflight request before the actual request.
OPTIONS /api HTTP/1.1
Access-Control-Request-Method: {request HTTP method}
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://www.devkuma.com
Access-Control-Allow-Methods: GET,POST,HEAD,OPTIONS
If custom request headers such as X-MyRequest and X-MyOption are used, the server must allow those headers using Access-Control-Allow-Headers. If custom response headers should be readable by the browser, the server must specify them with Access-Control-Expose-Headers.
Preflight request results can be cached using Access-Control-Max-Age.