CORS configuration for Rails APIs

Maya Patel Jan 2026
1 tab
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  # Development CORS - allow any localhost
  allow do
    origins(
      /http:\/\/localhost:\d+/,
      /http:\/\/127\.0\.0\.1:\d+/,
      'http://localhost:5173', # Vite default
      'http://localhost:3001'  # Alternative React dev server
    )

    resource '/api/*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head],
      credentials: true,
      expose: ['Authorization', 'X-Request-ID']
  end if Rails.env.development?

  # Production CORS - strict origin checking
  allow do
    origins ENV.fetch('ALLOWED_ORIGINS', '').split(',')

    resource '/api/*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head],
      credentials: true,
      expose: ['Authorization', 'X-Request-ID'],
      max_age: 86400 # Cache preflight for 24 hours
  end if Rails.env.production?

  # Public endpoints - no credentials
  allow do
    origins '*'

    resource '/api/public/*',
      headers: :any,
      methods: [:get, :options, :head],
      credentials: false
  end
end
1 file · ruby Explain with highlit

Cross-Origin Resource Sharing (CORS) allows browsers to make requests from React apps hosted on different domains than the Rails API. The rack-cors gem configures CORS middleware with fine-grained control over origins, methods, and headers. In development, I allow localhost origins with various ports for flexibility. Production restricts origins to specific domains. The credentials: true option enables cookies and authentication headers. expose headers make custom headers like Authorization accessible to JavaScript. Preflight OPTIONS requests happen automatically for complex requests. Wildcard origins (*) work for public APIs but disable credentials. Proper CORS configuration is essential for SPA architectures.