CORS Headers
What is CORS?
Cross-Origin Resource Sharing (CORS) is a security feature implemented in browsers to control access to resources located outside of a given domain. It is a mechanism that allows or denies requests for resources from a web page served by one domain (the "origin") to a server at a different domain.
Why Is CORS Required?
Traditionally, web browsers implement a security model known as the Same-Origin Policy (SOP). SOP restricts web pages from making requests to a different domain than the one that served the web page. While this policy prevents malicious scripts from interacting with resources from another domain, it also limits legitimate cross-origin requests essential for modern web applications.
CORS was introduced as a solution to safely override the SOP under certain conditions, allowing controlled cross-origin requests, thus enabling functionalities like APIs, CDNs, and external libraries to work seamlessly across domains.
How CORS Works
When a web application makes a cross-origin HTTP request, the browser automatically adds an Origin header to the request, indicating the domain of the web page. The server then decides whether to accept or reject this request based on its CORS policy.
If the server allows the request, it responds with the appropriate CORS HTTP headers, such as Access-Control-Allow-Origin, indicating which origins are permitted. The browser then permits the web page to access the response if the server's response matches the request's origin.
During a CORS request,
- the browser first sends a preflight request (
OPTIONSmethod) with theAccess-Control-Request-MethodandAccess-Control-Request-Headers(optional) to check if the server allows the actual request. - the server responds with the
Access-Control-Allow-Origin,Access-Control-Allow-Credentials(optional), andAccess-Control-Expose-Headers(optional) headers, indicating permissions and accessible data. - if the preflight is successful, the browser sends the actual request with the allowed method and headers.
CORS HTTP Headers
Example
Let's take a practical scenario. Here a client application hosted at https://example-client.com sends a cross-origin POST request to https://api.example-server.com with credentials and a custom header (X-Auth-Token).
Request Headers:
POST /resource HTTP/1.1
Host: api.example-server.com
Origin: https://example-client.com
Content-Type: application/json
X-Auth-Token: abc123
Server Response Headers:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example-client.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: X-Custom-Header
Content-Length: 123
In this example, the server permits the client from https://example-client.com to access the resource, allowing credentials to be sent and exposing the custom header X-Custom-Header.
CORS Request Headers
The client/browser sends the following headers to the server to identify the website initiating the API call.
| Header Name | Purpose | Example Value |
|---|---|---|
Origin | Identifies the origin of the request (originating website). | https://example-client.com |
Access-Control-Request-Method | Informs the server about the HTTP method intended for the actual request during a preflight request. | POST |
Access-Control-Request-Headers | Lists custom request headers the browser plans to send with the actual request during a preflight request. | Content-Type, X-Auth-Token |
CORS Response Headers
The server responds to the original (or pre-flight) request with the following headers, specifying what is permitted. This allows the web-browser to determine whether to proceed with the cross-domain call.
| Header Name | Purpose | Example Value |
|---|---|---|
Vary | Indicates headers that influence the response, potentially including Origin (relevant for CORS). | Origin |
Access-Control-Allow-Origin | Specifies which origins are permitted to access the resource. | https://example-client.com |
Access-Control-Allow-Credentials | Specifies whether credentials (cookies, authorization headers) are allowed in cross-origin requests. | true |
Access-Control-Expose-Headers | Lists custom response headers that should be accessible to client-side JavaScript. | X-Custom-Header, Content-Length |
Access-Control-Allow-Methods | Specifies the HTTP methods that are permitted when accessing the resource in cross-origin requests. | GET, POST, PUT, DELETE |
Access-Control-Allow-Headers | Lists the HTTP headers that can be used during the actual request. | Content-Type, X-Auth-Token |
Access-Control-Max-Age | Specifies how long the results of a preflight request can be cached by the browser. | 3600 |
Timing-Allow-Origin | Specifies origins that are allowed to view timing information via the Resource Timing API. | https://example-client.com |
The Origin header (in the request) and Vary header (in the response) plays a role in CORS as well, though they are not strictly CORS-specific headers.