Understanding CORS: Beginners guide

Understanding CORS: Beginners guide

·

4 min read

Every web developer has come across a CORS error in the browser console. Do you know why it's happening? Nope. then here is my brief understanding of CORS.

What?

CORS stands for Cross-Origin Resource Sharing. It is a mechanism followed by both server and client which helps to share data between different origins (domain, scheme, or port).

Why?

Most of the modern browsers implemented a same-origin policy which is a security mechanism that helps to prevent us from malicious attacks like CSRF.

The same-origin policy says a client example.com can access resources at a server hosted on example.com

cors_sop.jpg Here CORS comes into the picture to make a request from a client to the server that is hosted in a different origin like api.example.com

It looks like we are bypassing a security mechanism that browsers have. But not! CORS should be implemented in a way that doesn't affect the same-origin policy of browsers.

How?

Actually, we are making some exceptions to the same-origin policy by using some request and response headers.

There are two types of CORS requests preflight requests and simple requests.

Preflight Requests

The browser has to send a preflight request before the actual request to get permission from the server to make the actual request. This preflight request will not be triggered by the user, the browser itself makes this request with the OPTIONS header.

In that request, the browser will set some headers like Origin, Access-Control-Request-Method

OPTIONS /endpoint/ HTTP/1.1
Origin: https://www.example.com
Host: api.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Authorization, Content-Type
[Rest of request...]

CORS-preflight requests must never include credentials. The response to a preflight request must specify Access-Control-Allow-Credentials: true to indicate that the actual request can be made with credentials

In response, the server sends the headers like Access-Control-Allow-Methods, Access-Control-Allow-Origin which are allowed HTTP request methods that the server can process.

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://www.example.com
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type
Content-Type: application/json
[Rest of response...]

Now if the headers and methods are matched the browser will make the actual request that the user made.

POST /endpoint/ HTTP/1.1
Origin: https://www.example.com
Host: api.example.com
Authorization: [your token here...]
Content-Type: application/json
[Rest of request...]

cors_pre.jpg

Simple Requests

The requests which don't require preflight requests are simple requests. There are some conditions to be a simple request. The main three conditions are

  1. The request method should be one of GET, POST, HEAD
  2. Apart from the headers automatically set by the browsers , only the following can be set manually

    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type
  3. The only allowed values for the Content-Type header are:
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

for more refer here .

Request Headers

  • Origin: The client URL or domain from where the request is made is the origin.

  • Access-Control-Request-Method: Will be set only in preflight requests indicates the method type of the actual request.

  • Access-Control-Request-Headers: Will be set only in preflight requests indicates what are headers that used in the actual request.

Response Headers

  • Access-Control-Allow-Origin: This header specifies origins that are allowed by the servers to accept the requests.

    Access-Control-Allow-Origin specifies either a single origin which tells browsers to allow that origin to access the resource; or else — for requests without credentials — the "*" wildcard tells browsers to allow any origin to access the resource.

  • Access-Control-Expose-Headers: The allowed headers that clients can access are given this header.

  • Access-Control-Max-Age: Values in seconds for how long the preflight request can be cached.

  • Access-Control-Allow-Credentials: It is used during a response to a preflight request to indicate where the credentials are required for the actual request.

  • Access-Control-Allow-Methods: The allowed methods that the server can accept to access the resource are specified. To allow all methods * can be used as a wildcard.

  • Access-Control-Allow-Headers: This is a response for Access-Control-Request-Headers which have headers that can be used in the actual requests.

cors_head.jpg

Finally

The CORS error can be handled easily when you examine the headers of requests and responses. I have written this post with the help of this document. You may be curious to visit the official W3 documentation, which includes all of the technical specifications of CORS.

Images used in this post are taken from a Twitter post of RapidAPI.