CORS Plugin
Enables Cross-Origin Resource Sharing (CORS) in your application. Handles preflight requests and sets appropriate CORS headers for both simple and complex requests.
Quick Start
import { Server } from 'balda-js';
const server = new Server({
plugins: {
cors: {
origin: ['http://localhost:3000'],
credentials: true
}
}
});
Configuration
origin
Configure allowed origins:
// Allow all origins (development only)
cors: {
origin: '*'
}
// Allow specific origins
cors: {
origin: ['https://myapp.com', 'https://admin.myapp.com']
}
// Allow origins with regex
cors: {
origin: ['https://myapp.com', /^https:\/\/.*\.myapp\.com$/]
}
// Function-based validation
cors: {
origin: (origin) => {
const allowedOrigins = ['https://myapp.com'];
return allowedOrigins.includes(origin);
}
}
methods
Configure allowed HTTP methods:
// Default
cors: {
methods: ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE']
}
// Custom
cors: {
methods: ['GET', 'POST', 'PUT', 'DELETE']
}
// String format
cors: {
methods: 'GET,POST,PUT,DELETE'
}
allowedHeaders
Configure allowed request headers:
// Specific headers
cors: {
allowedHeaders: ['Content-Type', 'Authorization', 'X-API-Key']
}
// Allow all
cors: {
allowedHeaders: '*'
}
exposedHeaders
Expose response headers to the client:
cors: {
exposedHeaders: ['X-Total-Count', 'X-Page-Count']
}
credentials
Enable credentials (cookies, authorization headers):
cors: {
origin: ['https://myapp.com'], // Required with credentials
credentials: true
}
maxAge
Cache preflight results (in seconds):
cors: {
maxAge: 86400 // 24 hours
}
Complete Configuration
const server = new Server({
plugins: {
cors: {
origin: ['https://myapp.com'],
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
allowedHeaders: ['Content-Type', 'Authorization'],
exposedHeaders: ['X-Total-Count'],
credentials: true,
maxAge: 86400,
preflightContinue: false,
optionsSuccessStatus: 204
}
}
});
Route-Level CORS
Apply CORS to specific routes:
import { cors } from 'balda-js';
@controller('/api')
export class ApiController {
@get('/public', {
middleware: [cors({ origin: '*' })]
})
async publicEndpoint(req: Request, res: Response) {
res.json({ message: 'Public endpoint' });
}
@get('/private', {
middleware: [cors({
origin: ['https://myapp.com'],
credentials: true
})]
})
async privateEndpoint(req: Request, res: Response) {
res.json({ message: 'Private endpoint' });
}
}
Environment-Based Configuration
const isProduction = process.env.NODE_ENV === 'production';
const server = new Server({
plugins: {
cors: {
origin: isProduction
? process.env.ALLOWED_ORIGINS?.split(',')
: ['http://localhost:3000'],
credentials: isProduction,
maxAge: isProduction ? 86400 : undefined
}
}
});
Security Considerations
❌ Wildcard with Credentials
This doesn't work - credentials require specific origins:
cors: {
origin: '*',
credentials: true // Error!
}
✅ Specific Origins with Credentials
cors: {
origin: ['https://myapp.com', 'https://admin.myapp.com'],
credentials: true // Works!
}
Production Configuration
cors: {
origin: ['https://myapp.com'], // Specific origins only
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
maxAge: 86400
}
CORS Headers
Request Headers (from browser)
Origin- The origin of the requestAccess-Control-Request-Method- HTTP method for actual requestAccess-Control-Request-Headers- Headers for actual request
Response Headers (from server)
Access-Control-Allow-Origin- Allowed originsAccess-Control-Allow-Methods- Allowed HTTP methodsAccess-Control-Allow-Headers- Allowed headersAccess-Control-Expose-Headers- Headers exposed to clientAccess-Control-Allow-Credentials- Whether credentials allowedAccess-Control-Max-Age- Preflight cache duration
Preflight Requests
CORS automatically handles preflight OPTIONS requests:
OPTIONS /api/users
Origin: https://myapp.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, Authorization
→ Response:
Access-Control-Allow-Origin: https://myapp.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400