Web - Cross Origin Resource Sharing (CORS)

> (World Wide) Web - (W3|WWW) > (HTTP|HTTPS) - Hypertext Transfer Protocol

1 - About

Cross-origin resource sharing (CORS) is a mechanism occurring during a fetch that:

  • allows restricted resources (e.g. fonts) on a web page
  • to be requested from another domain outside the domain from which the first resource was served.

The main motivation behind Cross-Origin Resource Sharing (CORS) was to remove the same origin restriction from various APIs so that resources can be shared among different origins (i.e. servers).

Advertising

3 - Procedure

Although some validation and authorization can be performed by the server, it is the browser's responsibility to support these headers and honor the restrictions

Steps:

3.1 - Preflight request

The browser sends the OPTIONS request with an Origin HTTP header. It's called a “preflight” request, soliciting supported methods from the server

3.2 - Server answers with supported methods

The server respond with headers indicating what is allowed.

For instance, an Access-Control-Allow-Origin (ACAO) header in its response indicates which origin sites are allowed. For example:

Access-Control-Allow-Origin: http://www.example.com

3.3 - Send actual request

Upon browser “approval”, the browser sends the actual request with the actual HTTP request method (ie make available to the javascript)

4 - Headers

The HTTP headers that relate to CORS are

See documentation at https://fetch.spec.whatwg.org/

Advertising

4.1 - Request headers

4.1.1 - Origin

The HTTP - Origin (Header Field) request header indicates where a fetch originates from.

4.1.2 - Access-Control-Request-Method

Indicates which method a future CORS request to the same resource might use.

Access-Control-Request-Method: POST

4.1.3 - Access-Control-Request-Headers

Indicates which headers a future CORS request to the same resource might use.

4.2 - Response headers

If an URL resource implements CORS, the server need to define the request property that it will accept (ie

  • origins
  • HTTP methods
  • and type of data

4.2.1 - Access-Control-Allow-Origin

Access-Control-Allow-Origin define the allowed domain by the origin)

Access-Control-Allow-Origin: *  // Open to every domain
Access-Control-Allow-Origin: http://example.com // Open only to the domain example.com

Example of error that you can get:

Origin is not allowed by Access-Control-Allow-Origin
Advertising

4.2.2 - Access-Control-Allow-Credentials

Indicates whether the response can be shared when request’s credentials mode is “include”.

access-control-allow-credentials: true

4.2.3 - Access-Control-Expose-Headers

Access-Control-Allow-Headers: Content-Type

4.2.4 - Access-Control-Max-Age

4.2.5 - Access-Control-Allow-Methods

Access-Control-Allow-Methods: PUT, DELETE

4.2.6 - Access-Control-Allow-Headers

5 - Support

5.1 - Response to preflight request doesn't pass access control check

preflight request = Options request ?

Response to preflight request doesn't pass access control check No 'Access-Control-Allow-Origin' header is present

This error can be solved with one of the following solutions:

<!-- for directory -->
<Directory "/path/to/dir">
   <IfModule mod_headers.c>
      Header set Access-Control-Allow-Origin "*"
   </IfModule>
</Directory>
 
<!-- for specific file -->
<FilesMatch "\.(ttf|otf|eot|woff)$">
    <IfModule mod_headers.c>
        Header Set Access-Control-Allow-Origin "*"
    </IfModule>
</FilesMatch>
 
<!-- Mutliple Domain -->
<FilesMatch "\.(ttf|otf|eot|woff)$">
    <IfModule mod_headers.c>
        SetEnvIf Origin "http(s)?://(www\.)?(google.com|staging.google.com|development.google.com)$" AccessControlAllowOrigin=$0
        Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
    </IfModule>
</FilesMatch>
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Max-Age "1000"
Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token"

5.2 - The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'

Failed to load http://api.lavandiere.local/graphql.php: Response to preflight request doesn't pass access control check: 
The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' 
when the request's credentials mode is 'include'. Origin 'http://docker-host:78' is therefore not allowed access.

No luck

5.3 - Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.

Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.

Answer: Configure the server to set the header Access-Control-Allow-Headers

Example:

Header set Access-Control-Allow-Headers "Content-Type"

6 - Documentation / Reference

web/http/cors.txt · Last modified: 2019/02/09 13:59 by gerardnico