Daaang Amy
open main menu
Part of series: Learning the Backend

Figuring Out Cross Origin Requests

/ 4 min read

What are Cross Origin Requests (CORS)?

CORs is a mechanism that allows websites on one origin to be able to request data from another origin.

Definition of Origin

2 URLs are considered of the same origin if they have the same host, scheme, and port (if specified).

Host: meaning the domain name like foo.com or foo.org Scheme: whether it is http or https Port: the port number

Examples

URL AURL BSame Origin?
foo.comfoo.orgNo. they don’t have the same host
http://foo.comhttps://foo.comNo. they have different schemes
foo:1234.comfoo:9000.comNo. they have different port numbers
https://foo.comhttps://foo.comYes.

How Same-Origin Policy Works

All web browsers implement a security mechanism called same-origin policy. It makes sure the your webpage is not able to receive aka read data from a different origin.

Example of Same-Origin Policy

Let’s say you have a website called https://funkyshoes.com and your javascript wants to make an API request to another origin, something like https://api.funkyshoes.com. The request will go through and will return a response but the user’s web browser will block the response so that the javascript from https://funkyshoes.com will not be able to see it.

How To Relax The Same-Origin Policy

Access-Control-Allow-Origin: *

The Access-Control-Allow-Origin response header is used to indicate to a browser that it’s OK to share a response with a different origin.

Using a * means that we allow our web page to receive data from any origin.1 To allow a specific domain, simply set the header with the domain name.

Access-Control-Allow-Origin: https://example.com

⚠️ Warning: you can only specify EXACTLY ONE ORIGIN.

A Workaround The Origin Limit

Create a enableCors middleware. create a list of your allowed origins and once the request comes in, check the origin from the header against your list.

AKA whitelist your origins.

First, we will need to check that the request Origin header is an exact, case-sensitive match of the allowed origins. If the origin is allowed, we then set the Access-Control-Allow-Origin header with the origin that was sent with the request (the Origin header). Since the headers of the response will be different, a Vary: Origin2 header will need to be set in order to warn any caches that the response may be different.

TLDR;

  1. Create a list of allowed origins
  2. Check that the request’s Origin header is an exact, case-sensitive match of allowed origins
  3. If the origin is allowed, set the Access-Control-Allow-Origin with the same exact origin
  4. Also add a Vary: Origin header to the response

Authentication With CORS

If an API requires authentication, then the Allow-Control-Allow-Credentials: true3 header should also be set.

Preflight CORs Request

When the browser need to make a cross-origin request, sometimes it will send a preflight request first. The purpose of this is to determine whether or nothe real cross-origin request will be permitted by the server.

When the browser sends a preflight request, these are the relevant headers that will be checked by the server to identify it as a preflight request.

CORs Origin — Lets the API know what origin the preflight request is coming from.

Access-Control-Request-Method — Lets the API know what HTTP method will be used for the real request.

Access-Control-Request-Headers — lets the API know what HTTP headers will be sent with the real request. Note that it won’t list all the headers that the real request will use.

Preflight requests always have 3 components:

  • HTTP Method OPTIONS
  • Origin header
  • Aceess-Control-Request-Method header

How it works

  1. Browser sends preflight request
  2. server identifies request as a preflight
  3. server sends a 200 OK response with special headers. Allowing the real CORs request to proceed.

Special Headers in the 200 OK response:

  • Aceess-Control-Allow-Origin
    • reflects the value of the preflight’s Origin header
  • Aceess-Control-Allow-Methods
    • list of HTTP methods that can be used in real cross-origin requests
  • Aceess-Control-Allow-Headers
    • list of request headers that can be included in real cross-origin requests

Example:

Access-Control-Allow-Origin: <reflected trusted origin>
Access-Control-Allow-Methods: OPTIONS, PUT, PATCH, DELETE
Access-Control-Allow-Headers: Authorization, Content-Type

Why a 200 OK status rather than a 204 No Content status? Some browsers do not support the 204 response status and will block the real request.

Optional Header To Add To Preflight response

Access-Control-Max-Age: number of seconds that the information provided by Access-Control-Allow-Methods and Access-Control-Allow-Headers can be cached by browsers.

-1 means to disable it.

Browsers have their own default value for Access-Control-Max-Age but may also have a cap on how long the headers can be cached for4.

Footnotes

  1. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin

  2. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary

  3. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials

  4. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age#directives