What is CORS?

Definition

​Cross-origin resource sharing (CORS) is a standard for accessing web resources on different domains.

What does it mean?

CORS is browser-level mechanism that prevents client-side JS from accessing other domains than current one.
 

To remember: it is browser-level.

Overview

Core mechanism depends on browser adding Origin header to each cross-domain request. Browser expects server to respond with Access-Control-Accept-Origin header.

What does it mean?

Each cross-domain request is automatically extended with Origin header. If the server responds with empty Access-Control-Accept-Origin header or the one that does not contain current domain, browser will raise an exception.

Motivation

CORS was introduced to handle XMLHttpRequests. JSONP allows only to perform GET request, the motivation was to introduce secure way to handle all HTTP verbs.

Simple CORS

Simple CORS mechanism is used when the request sent is not expected to do any side-effects. It means that it is GET, HEAD or POST request and does not include any additional headers.

What does it mean?

CORS is browser-level. Browser assumes that GET, HEAD or POST without any additional headers should not make any side effects, therefore it's safe to send the request and check the headers on response. 

Simple CORS

Step by step

1. Client-side JS requests resource on the other domain (GET).

2. Browser is automatically adding Origin header.

3. Server is responding. It adds ​Access-Control-Allow-Origin containing Origin domain.

4. Browser accepts the header, the request is fulfilled.

Extended CORS

Extender CORS mechanism is used when the request sent is expected to do side-effects. It means that it is PUT, DELETE or any other with custom headers.

What does it mean?

CORS is browser-level. To prevent server from accepting request that potentially can do harm (side-effects), the browser is sending preflight request to check the headers before doing any side effects. This preflight request is using OPTIONS HTTP verb.

Extended CORS

Step by step

1. Client-side JS requests resource on the other domain (PUT).

2. Browser is automatically sending preflight request with Origin header.

3. Server is responding. It adds ​Access-Control-Allow-Origin containing Origin domain.

4. Browser accepts the header. It sends initial PUT request eventually using simple CORS mechanism.

Examples

Amazon S3

You deploy your app using ember-cli-deploy. Assets are uploaded to S3 (nice one!) and while testing you get...

Access to Font at 'https://my-app.s3.amazonaws.com/webfonts/yolo.woff' from origin 'https://my-app.s3.amazonaws.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.

Examples

Ember SPA

You run your Ember app on yolo-front.staging.my-app.com. Your backend runs on yolo.staging.my-app.com. And then...

Access to Resource at 'https://yolo.staging.my-app.com/users/me' from origin 'https://yolo.staging.my-app.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://yolo-front.staging.my-app.com' is therefore not allowed access.

Gems and addons

Enable CORS in your backend

Ruby on Rails

rack-cors - default in netguru stack

Node.js (express.js)

cors - tried in battlefield, it works :)

Summary

Most important to remember

CORS is browser-level security mechanism that you must eventually bump into while working with frontend.

 

It's not hard, it's quite easy and straightforward.

 

It is doing two requests that can't be cached, so you are probably wasting time.

Thanks

Made with Slides.com