CORS Configuration

Guide to configuring Cross-Origin Resource Sharing (CORS).

Table of Contents


Basic Setup

CorsMiddleware

Use CorsMiddleware to configure CORS.

use reinhardt::{CorsMiddleware, cors::CorsConfig};

let config = CorsConfig {
    allow_origins: vec!["https://example.com".to_string()],
    allow_methods: vec!["GET".to_string(), "POST".to_string()],
    allow_headers: vec!["Content-Type".to_string()],
    allow_credentials: true,
    max_age: Some(3600),
};

let middleware = CorsMiddleware::new(config);

CORS Configuration Options

CorsConfig

FieldTypeDefaultDescription
allow_originsVec<String>["*"]Allowed origins
allow_methodsVec<String>["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"]Allowed HTTP methods
allow_headersVec<String>["Content-Type", "Authorization"]Allowed request headers
allow_credentialsboolfalseWhether to allow credentials
max_ageOption<u64>Some(3600)Preflight cache duration (seconds)

Preflight Requests

Automatic OPTIONS Handling

CorsMiddleware automatically handles preflight requests (OPTIONS method).

use reinhardt::CorsMiddleware;

let middleware = CorsMiddleware::permissive();

// Preflight requests are automatically responded to with 204 No Content
// Access-Control-Allow-Origin: *
// Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
// Access-Control-Allow-Headers: Content-Type, Authorization
// Access-Control-Max-Age: 3600

Example Preflight Response

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 3600
Access-Control-Allow-Credentials: true

Development Environment

Permissive Mode

Use permissive() to allow all origins in development.

use reinhardt::CorsMiddleware;

// Allow all (development only)
let middleware = CorsMiddleware::permissive();

This is equivalent to:

use reinhardt::cors::CorsConfig;

let config = CorsConfig {
    allow_origins: vec!["*".to_string()],
    allow_methods: vec![
        "GET".to_string(),
        "POST".to_string(),
        "PUT".to_string(),
        "PATCH".to_string(),
        "DELETE".to_string(),
        "OPTIONS".to_string(),
    ],
    allow_headers: vec!["Content-Type".to_string(), "Authorization".to_string()],
    allow_credentials: false,
    max_age: Some(3600),
};

Production Environment

Single Origin

Allow only a specific origin.

use reinhardt::cors::CorsConfig;

let config = CorsConfig {
    allow_origins: vec!["https://app.example.com".to_string()],
    allow_methods: vec!["GET".to_string(), "POST".to_string()],
    allow_headers: vec!["Content-Type".to_string()],
    allow_credentials: false,
    max_age: Some(3600),
};

Multiple Origins

Allow multiple origins (comma-separated).

use reinhardt::cors::CorsConfig;

let config = CorsConfig {
    allow_origins: vec![
        "https://app1.example.com".to_string(),
        "https://app2.example.com".to_string(),
    ],
    // ... other config
};

Allow Credentials

Allow requests with cookies and authentication headers.

Note: When allow_credentials: true, you cannot use "*" in allow_origins.

use reinhardt::cors::CorsConfig;

let config = CorsConfig {
    // Cannot use wildcard with credentials
    allow_origins: vec!["https://app.example.com".to_string()],
    allow_methods: vec!["GET".to_string(), "POST".to_string()],
    allow_headers: vec![
        "Content-Type".to_string(),
        "Authorization".to_string(),
        "X-CSRF-Token".to_string(),
    ],
    allow_credentials: true,
    max_age: Some(7200), // 2 hours
};

Router Integration

Apply at Router Level

use reinhardt::ServerRouter;
use reinhardt::CorsMiddleware;

let router = ServerRouter::new()
    .with_middleware(CorsMiddleware::permissive());

Apply to Specific Routes

use reinhardt::ServerRouter;
use hyper::Method;

async fn api_handler(_req: reinhardt::Request) -> reinhardt::Result<reinhardt::Response> {
    Ok(reinhardt::Response::ok())
}
let router = ServerRouter::new()
    .function("/api/data", Method::GET, api_handler)
    .with_route_middleware(CorsMiddleware::permissive());

Middleware Order

CORS middleware should be applied as early as possible.

Recommended order:

  1. RequestIdMiddleware (request tracking)
  2. LoggingMiddleware (logging)
  3. CorsMiddleware (CORS handling)
  4. SecurityMiddleware (security headers)
  5. Other middleware...
use reinhardt::ServerRouter;
use reinhardt::{
    CorsMiddleware, LoggingMiddleware, SecurityMiddleware
};

let router = ServerRouter::new()
    .with_middleware(LoggingMiddleware::new())
    .with_middleware(CorsMiddleware::permissive())
    .with_middleware(SecurityMiddleware::new());

See Also