Cross-Origin Resource Sharing (CORS) middleware for Koa.js applications with comprehensive configuration options
npx @tessl/cli install tessl/npm-koa--cors@5.0.0@koa/cors provides Cross-Origin Resource Sharing (CORS) middleware for Koa.js applications, enabling developers to configure CORS policies for web applications and APIs. It offers comprehensive options for controlling access including origin specification, customizable allowed methods, configurable headers, credentials handling, and advanced security features.
npm install @koa/corsconst cors = require('@koa/cors');For ES modules:
import cors from '@koa/cors';const Koa = require('koa');
const cors = require('@koa/cors');
const app = new Koa();
// Enable CORS with default options
app.use(cors());
// Or with custom options
app.use(cors({
origin: 'https://example.com',
allowMethods: ['GET', 'POST', 'PUT', 'DELETE'],
allowHeaders: ['Content-Type', 'Authorization'],
credentials: true
}));
app.listen(3000);Creates CORS middleware for Koa.js applications with configurable options.
/**
* CORS middleware factory
* @param {Object} [options] - CORS configuration options
* @returns {Function} Koa.js middleware function
*/
function cors(options);Usage Examples:
// Default CORS (allows all origins with *)
const app = new Koa();
app.use(cors());
// Dynamic origin function
app.use(cors({
origin(ctx) {
const allowedOrigins = ['https://example.com', 'https://app.example.com'];
const requestOrigin = ctx.get('Origin');
return allowedOrigins.includes(requestOrigin) ? requestOrigin : false;
}
}));
// Comprehensive configuration
app.use(cors({
origin: 'https://trusted-domain.com',
allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],
exposeHeaders: ['X-Total-Count', 'X-Custom-Header'],
credentials: true,
maxAge: 86400, // 24 hours
keepHeadersOnError: true,
secureContext: false,
privateNetworkAccess: false
}));interface CorsOptions {
/** Access-Control-Allow-Origin header value */
origin?: string | ((ctx: Context) => Promise<string | false> | string | false);
/** Access-Control-Allow-Methods header value */
allowMethods?: string | string[];
/** Access-Control-Expose-Headers header value */
exposeHeaders?: string | string[];
/** Access-Control-Allow-Headers header value */
allowHeaders?: string | string[];
/** Access-Control-Max-Age header value in seconds */
maxAge?: string | number;
/** Access-Control-Allow-Credentials header */
credentials?: boolean | ((ctx: Context) => Promise<boolean> | boolean);
/** Add set headers to err.header if an error is thrown */
keepHeadersOnError?: boolean;
/** Enable Cross-Origin-Opener-Policy & Cross-Origin-Embedder-Policy headers */
secureContext?: boolean;
/** Handle Access-Control-Request-Private-Network requests */
privateNetworkAccess?: boolean;
}Option Details:
origin: Controls Access-Control-Allow-Origin header. Can be a string, function, or '*' (default). When credentials is true and origin is '*', it automatically uses the request's Origin header.
allowMethods: Sets allowed HTTP methods. Default: 'GET,HEAD,PUT,POST,DELETE,PATCH'. Accepts string or array format.
exposeHeaders: Specifies headers exposed to the client. Accepts string or array format.
allowHeaders: Sets allowed request headers. If not specified, uses the value from Access-Control-Request-Headers. Accepts string or array format.
maxAge: Cache duration for preflight requests in seconds. Must be string or number.
credentials: Controls Access-Control-Allow-Credentials header. Can be boolean or function. Default: false.
keepHeadersOnError: Whether to preserve CORS headers when errors occur. Default: true.
secureContext: Enables secure context headers (Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp). Default: false.
privateNetworkAccess: Handles private network access requests by responding with Access-Control-Allow-Private-Network: true. Default: false.
The returned middleware function that handles CORS for each request.
/**
* CORS middleware function
* @param {Object} ctx - Koa context object
* @param {Function} next - Next middleware in the chain
* @returns {Promise<void>}
*/
async function corsMiddleware(ctx, next);Behavior:
Vary: Origin header for proper cachingkeepHeadersOnError is truesecureContext option/**
* Koa context object (from Koa.js framework)
*/
interface Context {
/** Get request header value */
get(field: string): string;
/** Set response header */
set(field: string, value: string): void;
/** Set response status code */
status: number;
/** HTTP method of the request */
method: string;
/** Add value to Vary header */
vary(field: string): void;
}
/**
* Error object with headers property for CORS error handling
*/
interface CorsError extends Error {
headers?: Record<string, string>;
}When keepHeadersOnError is enabled (default), CORS headers are preserved in error responses:
// Error with CORS headers preserved
app.use(cors({ keepHeadersOnError: true }));
app.use(async (ctx, next) => {
try {
await next();
} catch (err) {
// CORS headers are automatically included in err.headers
ctx.status = err.status || 500;
ctx.body = { error: err.message };
ctx.set(err.headers || {});
}
});Dynamic CORS based on environment:
const isDevelopment = process.env.NODE_ENV === 'development';
app.use(cors({
origin: isDevelopment ? '*' : 'https://production-domain.com',
credentials: !isDevelopment
}));Function-based origin validation:
app.use(cors({
async origin(ctx) {
const requestOrigin = ctx.get('Origin');
// Check against database or external service
const isAllowed = await checkOriginPermissions(requestOrigin);
return isAllowed ? requestOrigin : false;
}
}));Conditional credentials:
app.use(cors({
origin: (ctx) => ctx.get('Origin'),
credentials: (ctx) => {
// Only allow credentials for specific paths
return ctx.path.startsWith('/api/auth');
}
}));