There are already a lot of resources about CORS out there.
I’m going to try and keep this short and sweet — useful tips for web devs.
About CORS
- CORS is a security mechanism based on HTTP headers.
- CORS must be configured on the web server and consumed by the browser.
- It is only relevant for web browsers, not requests from other software such as cURL or a Python script (which will ignore the configuration).
Why Does It Exist?
- You are on a website with
mydomain.com
. - All web browsers have a Same-Origin-Policy (SOP), preventing access to domains such as
sub.mydomain.com
orotherdomain.com
, as a security measure. - Cross-Origin Resource Sharing (CORS) is a mechanism to allow exceptions to this rule.
When Is It Triggered?
- If the schema, hostname, or port do not match, this is considered cross-origin.
- An example would be
https://mysite.com
andhttps://api.mysite.com
, which are different domains and hence cross-origin. - To avoid CORS for backend APIs, a common approach is to host the API under a subpath instead
https://mysite.com/api
, and avoid CORS concerns entirely.
Configuring CORS Correctly
Pre-Flight Requests
Browsers send a “pre-flight” request under certain conditions before making the actual request (for cross-origin requests).
A pre-flight request is a special
OPTIONS
request that checks the browser is allowed to submit to the API before making the actual request.As above, to avoid CORS and having to send two requests per API call, it’s possible to host an API under a subpath instead.
Access-Control Headers
- These headers control how CORS is enforced by the browser.
- They are set on the web server of the resource you are trying to access, e.g. your NGINX proxy or backend API.
Access-Control-Allow-Origins
- Which origins in the browser can call the API / webserver endpoints.
- Examples:
-
Access-Control-Allow-Origin: *
(allow all access) -
Access-Control-Allow-Origin: https://example.com
(specific protocol (https), domain (example.com), and port (443)))
-
Access-Control-Allow-Credentials
If cookies or HTTP basic auth should be sent with cross-origin requests.
Example:
Access-Control-Allow-Credentials: true
(allow).
Access-Control-Allow-Methods
- Specifies which HTTP methods are permitted for cross-origin requests.
- Example:
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
.
Access-Control-Expose-Headers
- Specifies which headers the browser can access from the response.
- Example:
Access-Control-Expose-Headers: Content-Length,Content-Range
. - A good example for this is the Content-Disposition which may contain the original filename of an attachment sent by the server:
- For the filename:
Content-Disposition: attachment; filename="myphoto.jpg"
- Allow the header to be read:
Access-Control-Expose-Headers: Content-Disposition
. - The browser can now download the file with the original filename.
- For the filename:
Other Headers
- Cross-Origin-Resource-Policy (CORP): controls how strict the CORS policy is:
-
same-origin
: Only allow requests from the exact same origin. -
same-site
: Allow requests from subdomains (e.g. api.example.com for example.com). -
cross-origin
: Allow all requests from any domain.
-
- Cross-Origin-Opener-Policy (COOP) & Cross-Origin-Embedder-Policy (COEP): typically used for security and performance optimizations. A common example is usage with the Origin Private File System (OPFS) and SharedArrayBuffer.
- Access-Control-Max-Age: defines how long the results of a pre-flight request can be cached before needing to run again.
Top comments (0)