CORS
Configure Cross-Origin Resource Sharing
CORS π
Configure CORS (Cross-Origin Resource Sharing) to allow or restrict cross-origin requests.
Built-in CORS Plugin π§
Enable CORS in your configuration:
import type { ConfigTypes } from "azurajs/config";
const config: ConfigTypes = {
plugins: {
cors: {
enabled: true,
origins: ["https://example.com"],
methods: ["GET", "POST", "PUT", "DELETE"],
allowedHeaders: ["Content-Type", "Authorization"],
},
},
};
export default config;Allow All Origins β οΈ
For development only:
cors: {
enabled: true,
origins: ["*"], // β οΈ Not recommended for production
}Multiple Origins π
Allow specific domains:
cors: {
enabled: true,
origins: [
"https://example.com",
"https://app.example.com",
"https://admin.example.com",
],
}Dynamic Origins π
Allow origins based on environment:
const allowedOrigins = process.env.NODE_ENV === "production"
? ["https://example.com"]
: ["http://localhost:3000", "http://localhost:5173"];
const config: ConfigTypes = {
plugins: {
cors: {
enabled: true,
origins: allowedOrigins,
},
},
};Custom CORS Middleware π οΈ
Create custom CORS middleware for advanced control:
import type { RequestHandler } from "azurajs/types";
export function createCorsMiddleware(options: {
origins: string[];
credentials?: boolean;
}): RequestHandler {
return async (req, res, next) => {
const origin = req.headers.origin;
if (origin && options.origins.includes(origin)) {
res.setHeader("Access-Control-Allow-Origin", origin);
} else if (options.origins.includes("*")) {
res.setHeader("Access-Control-Allow-Origin", "*");
}
res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS");
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
if (options.credentials) {
res.setHeader("Access-Control-Allow-Credentials", "true");
}
// Handle preflight
if (req.method === "OPTIONS") {
res.status(204).end();
return;
}
await next();
};
}
// Usage
const app = new AzuraClient();
app.use(createCorsMiddleware({
origins: ["https://example.com"],
credentials: true,
}));Credentials Support π
Allow cookies and authentication:
cors: {
enabled: true,
origins: ["https://example.com"], // Must be specific, not "*"
credentials: true, // Note: This requires custom middleware
}
// Custom middleware
const corsMiddleware: RequestHandler = async (req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "https://example.com");
res.setHeader("Access-Control-Allow-Credentials", "true");
res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
if (req.method === "OPTIONS") {
res.status(204).end();
return;
}
await next();
};
app.use(corsMiddleware);Preflight Requests βοΈ
Handle OPTIONS requests for preflight:
@Controller("/api/users")
export class UserController {
@Options()
handlePreflight(@Res() res: ResponseServer) {
res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
res.setHeader("Access-Control-Max-Age", "86400"); // Cache for 24 hours
res.status(204).end();
}
}Route-Specific CORS π―
Apply CORS only to specific routes:
const publicCors: RequestHandler = async (req, res, next) => {
if (req.url?.startsWith("/api/public")) {
res.setHeader("Access-Control-Allow-Origin", "*");
}
await next();
};
app.use(publicCors);Best Practices β¨
Never use "*" with credentials - Browsers will block the request
Be specific in production - List exact domains instead of using wildcards
Cache preflight requests - Use Access-Control-Max-Age to reduce OPTIONS requests
Test CORS thoroughly - Different browsers handle CORS slightly differently
Troubleshooting π
CORS Error: "No 'Access-Control-Allow-Origin' header"
// Make sure CORS is enabled
cors: {
enabled: true,
origins: ["https://your-frontend-domain.com"],
}CORS Error with Credentials
// Origin must be specific, not "*"
cors: {
origins: ["https://example.com"], // β
Specific
// origins: ["*"], // β Won't work with credentials
}Preflight Request Fails
// Ensure OPTIONS method is allowed
cors: {
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"], // Include OPTIONS
}