The minimum every developer must know about CORS
Published: 2022-05-18 04:00:06

---
title: The minimum every developer must know about CORS
published: true
date: 2022-05-18 02:47:52 UTC
tags: 
canonical_url: https://vietmle.com/posts/min_cors/
---

## What is CORS?

- **CORS** stands for **Cross-Origin Resource Sharing.**
- CORS is _HTTP-header based mechanism_ set by server to inform client side about _allowed origins_ (`<scheme>://<hostname>:<port>`) other than its own. It also indicates method and headers which the server is willing to support (example included below).
- **Most** of client browsers enforce CORS whenever _a cross-origin request_ is made. A request is cross-origin if it calls to outside origins, which are different from the one served the first resource.

CORS behaviour will be different between simple & “pre-flighted” requests. Let’s see the detail below.

### Simple requests

- Refer [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests) for full defition of simple request. For example, a GET request with no header is a simple request.

- A simple request is sent directly to server. Let’s see how it works in the example below:
![Source: MDN web docs](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ts6ybjjlon6ideb0wjvo.png)
    *Source: MDN web docs*

    -   **Request 1:** Client browser first load a web document from `domain-a.com` . The main request defines its `origin` as `domain-a.com`. This origin is then specified in the request header of subsequent requests.
        ```html
        Origin: <origin>
        ```
    -   **Request 2:** Client browser then send request to GET resource from `domain-a.com`. As comming from the same origin, the requested resource is fetched & rendered by browser.
    -   **Request 3:** similar to request 2, but the request now is sent to `domain-b.com` , which is a different origin.
        -   The resource will be successfully fetched, but ...
        -   It might be rendered by the browser only if in the response header, the allowed origin == `domain-a.com` (the request origin) or when it is a wildcard (*) meaning permit all origin.
        ```html
        Access-Control-Allow-Origin: <origin> | *
        ```


### “Pre-flighted” requests

- Any requests that are not simple is **“pre-flighted” one**.

- Unlike simple request, the browser will send a **_“preflight” request_** (OPTION method) to see if the actual one ( **”pre-flighted” one** ) is allowed by the server.

![Source: MDN web docs](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u92tq7hynq51dywjwm3z.png)
    *Source: MDN web docs*

- A _preflight request_ will include the following headers:

- Server responses with the following headers if it supports:

- Then, the browser will compare value in the response header against corresponding info of the actual request. **If all is allowed, the actual request is sent; otherwise, not.**

- The preflight request can also be cached in client side with the time-to-live indicated in `Access-Control-Max-Age` response header

## Final note

CORS is server-side security configurations that  **clients may enforce it.**

- Most browsers do (to avoid attack like CSRF).
- Some dev tools do not (like Postman).

## Further reading & references:

This article just covers surface of CORS. Further reading is highly recommended!

- Detailed visualization example: [https://www.youtube.com/watch?v=Ka8vG5miErk&t=621s](https://www.youtube.com/watch?v=Ka8vG5miErk&t=621s)
- Further analysis: [https://www.stackhawk.com/blog/what-is-cors/](https://www.stackhawk.com/blog/what-is-cors/)
- [https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)

Follow me (@vietmle_) on Twitter to get update whenever my new article is out!