skillbuilder

Understanding CORS: Cross-Origin Resource Sharing

In the modern web, applications are rarely self-contained. Frontends and backends are often hosted on different domains, subdomains, or ports. This separation introduces a security feature called CORS (Cross-Origin Resource Sharing).

What Is CORS?

CORS is a browser security mechanism that controls how web pages can make requests to a different domain than the one that served the web page. It is a protocol implemented in browsers, not on the server itself.

Example:

Your app is hosted at https://frontend.com, and it wants to fetch data from https://api.backend.com.

By default, the browser blocks this request due to the same-origin policy — a rule that allows scripts running on one origin to access resources on the same origin only.

What Is the Same-Origin Policy?

The same-origin policy allows a webpage to make requests only to the same domain, protocol, and port it came from. This protects the user from malicious cross-site requests.

So:

  • ✅ https://example.com/api → https://example.com/data
  • ❌ https://example.com/api → https://anotherdomain.com/data

This is where CORS comes in — it relaxes the same-origin policy under controlled circumstances.


How CORS Works

When a frontend makes a request to a different origin, the browser sends an extra HTTP request called a preflight request (for some types of calls like POST, PUT, or custom headers). This request uses the OPTIONS method.

Example:

OPTIONS /data HTTP/1.1
Origin: https://frontend.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type

The server must respond with:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://frontend.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: Content-Type

If the headers are missing or incorrect, the browser blocks the request.


Common CORS Response Headers

  • Access-Control-Allow-Origin Specifies the origin allowed to access the resource. Example: Access-Control-Allow-Origin: * (public access) or a specific origin.
  • Access-Control-Allow-Methods What HTTP methods are permitted (e.g., GET, POST, PUT, DELETE).
  • Access-Control-Allow-Headers Which headers can be used in the actual request (e.g., Authorization, Content-Type).
  • Access-Control-Allow-Credentials If true, allows credentials like cookies or HTTP authentication to be included.

Enabling CORS on the Server

Express.js (Node.js)

const cors = require('cors');
const express = require('express');
const app = express();

app.use(cors({
  origin: 'https://frontend.com',
  credentials: true
}));

Ruby on Rails

# config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'https://frontend.com'
    resource '*', headers: :any, methods: [:get, :post, :options], credentials: true
  end
end

CORS Is Not a Security Wall

CORS is not a server-side security measure. It only tells the browser how to behave. Malicious clients like Postman or curl can still send requests — it’s your server’s job to authenticate and authorize properly.


Common CORS Errors

  • “No ‘Access-Control-Allow-Origin’ header is present” → Your server isn’t sending the right CORS headers.
  • “CORS policy: Request header field is not allowed” → You used a custom header without adding it to Access-Control-Allow-Headers.
  • Preflight request fails with 403 → Your server blocks the OPTIONS method.

Summary

  • CORS enables secure cross-origin communication between browsers and servers.
  • It relies on specific HTTP headers to permit or deny access.
  • Always configure CORS deliberately — be careful with Access-Control-Allow-Origin: * and credentials.

0