Single Origin with Credentials

Configure CORS to allow one specific origin with credentials support. Understand the interplay between Allow-Origin, Allow-Credentials, and the Vary header.

Basic CORS

Detailed Explanation

Specific Origin + Credentials

When your frontend and API live on different subdomains and the API uses cookies or Authorization headers, you need a targeted CORS policy that names the exact origin and enables credentials.

Generated Headers

Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 3600
Vary: Origin

Why Not Wildcard?

Browsers enforce a strict rule: if Access-Control-Allow-Credentials is true, the Allow-Origin header must be the exact requesting origin, not *. Violating this rule causes the browser to block the response without any visible server-side error — a silent failure that is notoriously difficult to debug.

The Vary Header

When your server dynamically sets Access-Control-Allow-Origin based on the incoming Origin request header, you must include Vary: Origin in the response. This tells CDNs and browser caches to store separate cached versions per origin, preventing one origin's CORS response from being served to a different origin.

Express.js Example

const cors = require("cors");

app.use(cors({
  origin: "https://app.example.com",
  methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
  allowedHeaders: ["Content-Type", "Authorization"],
  credentials: true,
  maxAge: 3600,
}));

Cookie Considerations

For cookies to be sent cross-origin, three conditions must all be true: the server sends Allow-Credentials: true, the client sets fetch({ credentials: "include" }) (or withCredentials: true for XHR), and the cookie's SameSite attribute is set to None with Secure.

Use Case

A SaaS application where the dashboard at app.example.com talks to the API at api.example.com. Session cookies need to travel cross-origin for authentication, so credentials must be enabled with the exact frontend origin.

Try It — CORS Header Builder

Open full tool