Use Cases (अपडेट: 2/6/2026)

Claude Code के साथ CORS Configuration Guide: सुरक्षित Cross-Origin API

Claude Code से CORS सुरक्षित configure करें: preflight, credentials, origin allowlist, test commands और review prompts.

Claude Code के साथ CORS Configuration Guide: सुरक्षित Cross-Origin API

Claude Code से CORS सही तरीके से configure करें

Frontend अगर localhost:3000 पर है और API localhost:8787 पर, तो browser तुरंत CORS error दिखा सकता है। जल्दी में लोग अक्सर Access-Control-Allow-Origin: * जोड़ देते हैं, लेकिन API में cookie, Authorization header या admin panel हो तो यह unsafe हो सकता है।

CORS, यानी Cross-Origin Resource Sharing, वह browser mechanism है जिससे server बताता है कि कौन से दूसरे origins उसकी response पढ़ सकते हैं। Origin scheme, host और port का combination है। https://app.example.com, https://api.example.com, http://localhost:3000 और http://localhost:5173 अलग-अलग origins हैं।

यह guide CORS configuration को ऐसे हिस्सों में तोड़ती है जिन्हें Claude Code से generate कराने के बाद आप review कर सकें। इसमें Express, Fastify, Cloudflare Workers और Next.js Route Handler के copy-paste examples, preflight, credentials, origin allowlist, test commands और Claude Code review prompts शामिल हैं।

सबसे जरूरी बात: CORS authentication नहीं है। यह सिर्फ control करता है कि browser JavaScript cross-origin response पढ़ सके या नहीं। यह curl, server-to-server calls या unauthorized users को नहीं रोकता। API authentication, authorization, CSRF, rate limiting और security headers अलग से design करें।

sequenceDiagram
  participant Browser as Browser
  participant API as API server
  Browser->>API: OPTIONS /api/messages<br/>Origin + Access-Control-Request-*
  API-->>Browser: 204 + Access-Control-Allow-*
  Browser->>API: POST /api/messages<br/>Cookie or Authorization
  API-->>Browser: 200 + Access-Control-Allow-Origin

Code लिखने से पहले decisions

Claude Code से CORS middleware लिखवाने से पहले ये चार बातें तय करें। अगर prompt vague होगा, तो वह demo-friendly लेकिन production के लिए dangerous full-open config दे सकता है।

DecisionExampleध्यान दें
Allowed originshttps://app.example.com, https://admin.example.comPath या trailing slash नहीं
CredentialsCookie, Authorization headerCookie flow में SameSite=None; Secure भी check करें
MethodsGET,POST,PUT,PATCH,DELETE,OPTIONSसिर्फ इस्तेमाल होने वाले methods allow करें
HeadersContent-Type,Authorization,X-Request-IDPreflight request से match होना चाहिए

Preflight browser की permission check request है। JSON POST, Authorization, PUT, DELETE या custom headers से पहले browser अक्सर OPTIONS भेजता है। अगर response में matching Access-Control-Allow-Methods और Access-Control-Allow-Headers नहीं हैं, तो actual request भेजी ही नहीं जाती।

Express configuration

यह example Node.js 20 या उससे नए version के लिए है। Express का official cors middleware origin में function ले सकता है, इसलिए हर request को allowlist से check किया जा सकता है। API credentials support करती है, इसलिए केवल allowed origins reflect होंगे और credentials: true लगाया जाएगा।

npm init -y
npm install express cors
node server.mjs
// server.mjs
import express from "express";
import cors from "cors";

const app = express();

const allowedOrigins = new Set([
  "https://app.example.com",
  "https://admin.example.com",
  "http://localhost:3000",
  "http://localhost:5173",
]);

function isAllowedOrigin(origin) {
  if (!origin) return true;
  if (allowedOrigins.has(origin)) return true;
  return process.env.NODE_ENV !== "production" && /^http:\/\/localhost:\d+$/.test(origin);
}

const corsOptions = {
  origin(origin, callback) {
    callback(null, isAllowedOrigin(origin));
  },
  credentials: true,
  methods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
  allowedHeaders: ["Content-Type", "Authorization", "X-Request-ID"],
  exposedHeaders: ["X-Request-ID"],
  maxAge: 86400,
  optionsSuccessStatus: 204,
};

app.use((req, res, next) => {
  const origin = req.headers.origin;
  if (origin && !isAllowedOrigin(origin)) {
    return res.status(403).json({ error: "Origin not allowed" });
  }
  next();
});

app.use(cors(corsOptions));
app.use(express.json());

app.get("/api/health", (_req, res) => {
  res.setHeader("X-Request-ID", crypto.randomUUID());
  res.json({ ok: true });
});

app.post("/api/messages", (req, res) => {
  res.setHeader("X-Request-ID", crypto.randomUUID());
  res.json({ ok: true, received: req.body });
});

app.listen(8787, () => {
  console.log("API listening on http://localhost:8787");
});

Production में NODE_ENV=production set करें और allowedOrigins में सिर्फ real domains रखें। जिन requests में Origin header नहीं है वे browser CORS requests नहीं होतीं, इसलिए sample उन्हें allow करता है; API key, JWT और user permissions फिर भी auth middleware में check होने चाहिए।

Fastify configuration

Fastify में @fastify/cors use करें। Official README में origin के लिए boolean, string, array, RegExp और function supported हैं, लेकिन Set-based exact match audit करना आसान है। Broad regex तभी use करें जब सच में जरूरत हो।

npm init -y
npm install fastify @fastify/cors
node server.mjs
// server.mjs
import Fastify from "fastify";
import cors from "@fastify/cors";

const app = Fastify({ logger: true });

const allowedOrigins = new Set([
  "https://app.example.com",
  "https://admin.example.com",
  "http://localhost:3000",
  "http://localhost:5173",
]);

function isAllowedOrigin(origin) {
  if (!origin) return true;
  if (allowedOrigins.has(origin)) return true;
  return process.env.NODE_ENV !== "production" && /^http:\/\/localhost:\d+$/.test(origin);
}

app.addHook("onRequest", async (request, reply) => {
  const origin = request.headers.origin;
  if (origin && !isAllowedOrigin(origin)) {
    return reply.code(403).send({ error: "Origin not allowed" });
  }
});

await app.register(cors, {
  origin(origin, callback) {
    callback(null, isAllowedOrigin(origin));
  },
  credentials: true,
  methods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
  allowedHeaders: ["Content-Type", "Authorization", "X-Request-ID"],
  exposedHeaders: ["X-Request-ID"],
  maxAge: 86400,
  strictPreflight: true,
});

app.get("/api/health", async () => ({ ok: true }));

app.post("/api/messages", async (request) => {
  return { ok: true, received: request.body };
});

await app.listen({ port: 8787, host: "0.0.0.0" });

Fastify में plugin और hook order important है। अगर auth hook CORS plugin से पहले OPTIONS reject कर देता है, तो browser actual request नहीं भेजेगा। Claude Code से review कराते समय registration order भी check करवाएँ।

Cloudflare Workers configuration

Cloudflare Workers standard Fetch API use करता है। OPTIONS को explicitly handle करें, success और error दोनों responses पर CORS headers लगाएँ, और origin के हिसाब से response बदलता है तो Vary: Origin जोड़ें।

// src/index.ts
const allowedOrigins = new Set([
  "https://app.example.com",
  "https://admin.example.com",
  "http://localhost:3000",
]);

function getCorsHeaders(request: Request): HeadersInit | null {
  const origin = request.headers.get("Origin");
  if (!origin) return {};
  if (!allowedOrigins.has(origin)) return null;

  return {
    "Access-Control-Allow-Origin": origin,
    "Access-Control-Allow-Credentials": "true",
    "Access-Control-Allow-Methods": "GET,POST,OPTIONS",
    "Access-Control-Allow-Headers": "Content-Type,Authorization,X-Request-ID",
    "Access-Control-Max-Age": "86400",
    "Vary": "Origin",
  };
}

export default {
  async fetch(request: Request): Promise<Response> {
    const corsHeaders = getCorsHeaders(request);
    if (corsHeaders === null) {
      return Response.json({ error: "Origin not allowed" }, { status: 403 });
    }

    if (request.method === "OPTIONS") {
      return new Response(null, { status: 204, headers: corsHeaders });
    }

    const url = new URL(request.url);
    if (url.pathname === "/api/messages" && request.method === "POST") {
      const body = await request.json().catch(() => ({}));
      return Response.json({ ok: true, received: body }, { headers: corsHeaders });
    }

    return Response.json({ error: "Not found" }, { status: 404, headers: corsHeaders });
  },
};

Workers में common mistake है कि headers सिर्फ success path पर लगाए जाते हैं। अगर OPTIONS, 401, 403 या 500 पर CORS headers नहीं हैं, तो DevTools सिर्फ CORS failure दिखा सकता है और असली application error छिप जाती है।

Next.js Route Handler configuration

App Router में app/api/.../route.ts Web standard Request और Response use करता है। Next.js docs response पर CORS headers लगाने का तरीका दिखाते हैं; credentials वाली API के लिए * की जगह allowlist use करें।

// app/api/messages/route.ts
const allowedOrigins = new Set([
  "https://app.example.com",
  "https://admin.example.com",
  "http://localhost:3000",
]);

function getCorsHeaders(request: Request): HeadersInit | null {
  const origin = request.headers.get("Origin");
  if (!origin) return {};
  if (!allowedOrigins.has(origin)) return null;

  return {
    "Access-Control-Allow-Origin": origin,
    "Access-Control-Allow-Credentials": "true",
    "Access-Control-Allow-Methods": "POST,OPTIONS",
    "Access-Control-Allow-Headers": "Content-Type,Authorization,X-Request-ID",
    "Access-Control-Max-Age": "86400",
    "Vary": "Origin",
  };
}

export async function OPTIONS(request: Request) {
  const headers = getCorsHeaders(request);
  if (headers === null) {
    return Response.json({ error: "Origin not allowed" }, { status: 403 });
  }
  return new Response(null, { status: 204, headers });
}

export async function POST(request: Request) {
  const headers = getCorsHeaders(request);
  if (headers === null) {
    return Response.json({ error: "Origin not allowed" }, { status: 403 });
  }

  const body = await request.json().catch(() => ({}));
  return Response.json({ ok: true, received: body }, { headers });
}

next.config.js का headers() static public API headers के लिए ठीक है। अगर हर request में origin check करना है, तो Route Handler के अंदर logic ज्यादा readable होता है।

Test commands

curl से preflight और actual request अलग-अलग verify करें। देखें कि Access-Control-Allow-Origin request के Origin से exactly match करता है या नहीं, और Access-Control-Allow-Credentials: true सिर्फ allowed origins के लिए आता है या नहीं।

curl -i -X OPTIONS http://localhost:8787/api/messages \
  -H "Origin: http://localhost:3000" \
  -H "Access-Control-Request-Method: POST" \
  -H "Access-Control-Request-Headers: Content-Type, Authorization"

curl -i -X POST http://localhost:8787/api/messages \
  -H "Origin: http://localhost:3000" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer dev-token" \
  --data '{"text":"hello"}'

curl -i -X OPTIONS http://localhost:8787/api/messages \
  -H "Origin: https://evil.example" \
  -H "Access-Control-Request-Method: POST"

Browser में credentials test ऐसे करें। अगर credentials: "include" है, तो wildcard CORS response browser reject कर देगा।

await fetch("http://localhost:8787/api/messages", {
  method: "POST",
  credentials: "include",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "Bearer dev-token",
  },
  body: JSON.stringify({ text: "hello" }),
});

Practical use cases

पहला case है SPA और API अलग domains पर। अगर React app https://app.example.com पर है और API https://api.example.com पर, तो explicit allowlist चाहिए। Login cookies हों तो credentials, cookie attributes और CSRF साथ में review करें।

दूसरा case admin frontend है। https://admin.example.com को allowlist में जोड़ सकते हैं, लेकिन CORS को admin permission check न समझें। Authorization logic API code में होना चाहिए।

तीसरा case Cloudflare Worker को BFF या lightweight proxy की तरह use करना है। Browser Worker को call करता है, Worker upstream API को call करता है। Browser को लौटने वाली Worker response पर फिर भी सही CORS headers चाहिए।

चौथा case public read-only API है। अगर cookies, Authorization और private data नहीं हैं, तो Access-Control-Allow-Origin: * acceptable हो सकता है। Future में auth add होने की संभावना हो तो शुरुआत से allowlist रखें।

Specific pitfalls

PitfallResultFix
* और credentials: true साथ रखनाBrowser response block करता हैExplicit origin return करें
https://app.example.com/ register करनाTrailing slash match तोड़ता हैhttps://app.example.com रखें
सिर्फ localhost allow करनाDifferent ports fail होते हैंhttp://localhost:3000 लिखें
OPTIONS पर auth require करनाPreflight 401/403 पर रुकता हैPreflight auth से पहले handle करें
Error responses पर CORS नहींDevTools असली error छिपाता है4xx/5xx पर भी headers जोड़ें
CDN origin-specific headers cache करता हैHeaders mix हो सकते हैंVary: Origin जोड़ें
CORS को authorization माननाNon-browser clients फिर भी call करते हैंAuth, authorization और CSRF अलग implement करें

MDN साफ कहता है कि credentials वाली CORS request में Access-Control-Allow-Origin: * use नहीं किया जा सकता। अगर Claude Code यह combination generate करे, तो उसे bug मानकर ठीक करें।

Claude Code review prompts

Review this repository's CORS configuration.
Check:
- No Access-Control-Allow-Origin: * when credentials are enabled
- Allowlist uses exact scheme/host/port matching
- OPTIONS preflight runs before authentication middleware
- 4xx/5xx responses include the required CORS headers
- Vary: Origin is present when responses vary by origin
If changes are needed, propose the smallest safe diff.
Diagnose this CORS error by cause.
Browser error:
<paste the full DevTools Console message>

curl preflight:
<paste curl -i -X OPTIONS output>

Expected origin:
https://app.example.com

Read the relevant API files and return reproduction steps, root cause, fix, and tests.
Review the Express/Fastify/Next.js/Workers CORS implementation as a security reviewer.
Focus on:
- Whether request origins are blindly reflected
- Whether localhost remains enabled in production
- Whether Authorization is allowed without proper authorization checks
- Whether cookie flows mention SameSite=None; Secure and CSRF protection
- Whether test commands separate preflight and the real request
Group findings as Critical, Must fix, and Improvement.

Specification समझने के लिए MDN CORS guide को base रखें। Implementation के लिए Express cors middleware, @fastify/cors, Cloudflare Workers CORS examples और Next.js Route Handlers देखें। Claude Code workflows के लिए Claude Code commands उपयोगी है।

इसे API development guide, web security headers guide, Cloudflare Workers guide और code review workflow checklist के साथ पढ़ें।

Next step

Sample domains को अपने domains से replace करने के बाद ऊपर वाले review prompts repository पर चलाएँ। फिर Claude Code security best practices से cookies, CSRF, authorization और headers को साथ में review करें। Client project या internal platform में यह checklist review artifact बन सकती है और paid implementation support या reusable templates की proposal में मदद करती है।

असल में test करने का result

Masa के local test में Express और Fastify examples localhost:8787 पर चले; Origin: http://localhost:3000 से preflight और POST सफल रहे, जबकि https://evil.example ने 403 लौटाया। सबसे आसानी से छूटने वाली बातें error responses पर CORS headers और Workers में explicit OPTIONS handling थीं। सबसे stable workflow यह रहा: पहले allowlist implement करें, फिर curl checks चलाएँ, फिर Claude Code से verify कराएँ कि wildcard plus credentials नहीं है, जहाँ जरूरत है वहाँ Vary: Origin है, और localhost production में नहीं जाता।

#Claude Code #CORS #security #API #web development
मुफ़्त

मुफ़्त PDF: Claude Code cheatsheet

Email डालें और commands, review habits तथा safe workflow वाली एक-page PDF पाएँ.

हम आपका data सुरक्षित रखते हैं और spam नहीं भेजते.

Masa

लेखक के बारे में

Masa

Claude Code workflow और team adoption पर काम करने वाला engineer.