0
0
Ruby on Railsframework~15 mins

CORS configuration in Ruby on Rails - Deep Dive

Choose your learning style9 modes available
Overview - CORS configuration
What is it?
CORS configuration is how a Rails application controls which other websites can ask it for data. It stands for Cross-Origin Resource Sharing, a security feature in browsers that stops unwanted websites from reading your app's data. By setting CORS rules, you tell browsers which external sites are allowed to talk to your Rails backend. This keeps your app safe while letting trusted sites access your resources.
Why it matters
Without CORS configuration, browsers block requests from other websites, breaking features like APIs or frontend apps hosted separately. If you don't set it up, your users might see errors or missing data when your app tries to share information across sites. Proper CORS setup ensures smooth, secure communication between your Rails backend and other web apps, improving user experience and protecting data.
Where it fits
Before learning CORS configuration, you should understand HTTP basics and how web browsers enforce security. Knowing Rails middleware and how requests flow through your app helps too. After mastering CORS, you can explore API authentication, security headers, and advanced Rails security practices.
Mental Model
Core Idea
CORS configuration is a gatekeeper that tells browsers which external websites can safely access your Rails app's data.
Think of it like...
Imagine your Rails app is a private clubhouse. CORS configuration is the guest list that the doorman checks before letting visitors in. Only guests on the list can enter and interact; others are politely turned away.
┌───────────────┐       ┌───────────────┐       ┌───────────────┐
│ External Site │──────▶│ Browser (Gate)│──────▶│ Rails Backend │
└───────────────┘       └───────────────┘       └───────────────┘
         │                      │                      │
         │  Sends request       │ Checks CORS rules    │ Processes request
         │                      │                      │
         ▼                      ▼                      ▼
   Allowed? ───────────────▶ Yes ───────────────▶ Response
         │
         └──────────────▶ No ───────────────▶ Blocked by browser
Build-Up - 7 Steps
1
FoundationWhat is CORS and Why It Exists
🤔
Concept: Introduce the basic idea of CORS as a browser security feature that controls cross-site requests.
Browsers prevent web pages from making requests to a different domain than the one that served the page. This is called the Same-Origin Policy. CORS is a way for servers to say, "It's okay for these other sites to ask me for data." Without CORS, your Rails app would only respond to requests from its own domain.
Result
You understand that CORS is a browser rule that your Rails app can configure to allow or block requests from other websites.
Understanding CORS as a browser-enforced security rule explains why your Rails app needs explicit configuration to share data safely.
2
FoundationHow Rails Handles CORS Requests
🤔
Concept: Explain that Rails uses middleware to process CORS headers before reaching your app logic.
Rails apps use middleware like 'rack-cors' to add CORS headers to responses. When a browser sends a request from another site, the middleware checks if the request's origin is allowed. If yes, it adds headers that tell the browser to accept the response. If not, the browser blocks the response.
Result
You see that CORS is handled early in the request cycle, controlling access before your Rails code runs.
Knowing that middleware manages CORS helps you understand where and how to configure it in Rails.
3
IntermediateConfiguring rack-cors in Rails
🤔Before reading on: Do you think CORS settings go in controller code or middleware configuration? Commit to your answer.
Concept: Learn how to install and configure the rack-cors gem to set CORS rules in Rails.
Add 'rack-cors' to your Gemfile and run bundle install. Then, in config/application.rb or config/initializers/cors.rb, add a configuration block specifying allowed origins, resources, and HTTP methods. For example: Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do origins 'https://trustedsite.com' resource '*', headers: :any, methods: [:get, :post, :options] end end
Result
Your Rails app now sends CORS headers allowing requests from 'https://trustedsite.com' with specified methods.
Configuring CORS in middleware centralizes access control, keeping your app secure and maintainable.
4
IntermediateUnderstanding Preflight Requests
🤔Before reading on: Do you think all cross-origin requests trigger a preflight OPTIONS request? Commit to yes or no.
Concept: Explain the browser's preflight OPTIONS request that checks permissions before sending actual data requests.
For some requests (like POST with JSON), browsers first send an OPTIONS request to ask the server if the real request is allowed. Your Rails app must respond to OPTIONS with correct CORS headers. rack-cors handles this automatically if configured properly.
Result
You understand why your Rails app sometimes receives OPTIONS requests and how CORS configuration handles them.
Knowing about preflight requests prevents confusion when debugging cross-origin request failures.
5
IntermediateAllowing Multiple Origins and Dynamic Origins
🤔Before reading on: Can rack-cors accept a list of origins or a dynamic function? Commit to your answer.
Concept: Learn how to allow multiple or dynamic origins in CORS configuration for flexible access control.
You can specify multiple origins by listing them in the origins method, like origins 'https://site1.com', 'https://site2.com'. For dynamic control, you can pass a lambda that checks the origin string and returns true or false. This lets you allow or deny origins based on custom logic.
Result
Your Rails app can flexibly allow requests from many or conditionally approved sites.
Dynamic origin control lets you balance security and usability in complex environments.
6
AdvancedSecuring CORS to Prevent Data Leaks
🤔Before reading on: Is it safe to set origins to '*' in production? Commit to yes or no.
Concept: Understand the security risks of overly permissive CORS settings and how to tighten them.
Setting origins to '*' allows any site to access your API, which can expose sensitive data or enable attacks. Instead, specify exact trusted domains. Also, limit allowed HTTP methods and headers. Use credentials: false unless you need cookies or authentication headers shared cross-origin, which requires extra care.
Result
You know how to configure CORS securely to protect your Rails app and users.
Recognizing CORS risks helps prevent serious security vulnerabilities in production.
7
ExpertCORS and Rails API Mode Internals
🤔Before reading on: Does Rails API mode change how CORS middleware works? Commit to yes or no.
Concept: Explore how Rails API mode affects middleware stack and CORS behavior internally.
Rails API mode uses a slimmer middleware stack for performance. rack-cors must be explicitly added because default middleware like session or cookies are removed. This means CORS configuration is critical to enable cross-origin requests in API-only apps. Also, understand how middleware order affects header setting and request handling.
Result
You grasp how Rails API mode changes CORS setup and why middleware order matters.
Knowing Rails internals prevents subtle bugs and ensures reliable CORS behavior in API apps.
Under the Hood
When a browser makes a cross-origin request, it sends the Origin header with the request. The Rails app's rack-cors middleware intercepts this request early, checks if the Origin matches allowed origins, and if so, adds Access-Control-Allow-Origin and other CORS headers to the response. For preflight OPTIONS requests, rack-cors responds with allowed methods and headers without invoking the main app logic. The browser reads these headers to decide if it should allow the frontend JavaScript to access the response data.
Why designed this way?
Browsers enforce the Same-Origin Policy to protect users from malicious sites stealing data. CORS was designed as a controlled relaxation of this policy, letting servers explicitly declare trusted origins. rack-cors middleware fits into Rails as a modular, configurable layer to handle these headers cleanly without cluttering app code. This separation keeps security concerns centralized and easier to maintain.
┌───────────────┐
│ Browser sends │
│ request with  │
│ Origin header │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ rack-cors     │
│ middleware    │
│ checks Origin │
│ against rules │
└──────┬────────┘
       │
       │ Allowed?
       │ Yes
       ▼
┌───────────────┐
│ Add CORS      │
│ headers to    │
│ response      │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Rails app     │
│ processes     │
│ request       │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does setting origins to '*' always allow all cross-origin requests including credentials? Commit to yes or no.
Common Belief:Setting origins to '*' means any website can access your API with credentials like cookies.
Tap to reveal reality
Reality:Browsers block credentialed requests if Access-Control-Allow-Origin is '*'. You must specify exact origins to allow credentials.
Why it matters:Misconfiguring this leads to failed authenticated requests and broken user sessions.
Quick: Do you think CORS is a server-side security feature? Commit to yes or no.
Common Belief:CORS protects the server from unauthorized access by blocking bad requests.
Tap to reveal reality
Reality:CORS is enforced by browsers on the client side; servers respond with headers but do not block requests themselves.
Why it matters:Assuming CORS is server-side security can cause developers to neglect proper backend authentication and authorization.
Quick: Do you think all cross-origin requests trigger a preflight OPTIONS request? Commit to yes or no.
Common Belief:Every cross-origin request sends a preflight OPTIONS request first.
Tap to reveal reality
Reality:Only requests with certain methods or headers trigger preflight; simple GET requests usually do not.
Why it matters:Misunderstanding this can lead to confusion when debugging CORS issues and unnecessary server handling.
Quick: Can rack-cors configuration be placed anywhere in Rails code with the same effect? Commit to yes or no.
Common Belief:You can configure rack-cors anywhere in Rails and it will work the same.
Tap to reveal reality
Reality:rack-cors must be inserted early in the middleware stack to handle requests before other middleware.
Why it matters:Placing CORS config too late causes headers not to be set, breaking cross-origin requests.
Expert Zone
1
Middleware order is critical: rack-cors must be inserted before other middleware that might consume the request or modify headers.
2
Dynamic origin lambdas can introduce performance overhead and complexity; caching allowed origins can improve efficiency.
3
In API-only Rails apps, missing rack-cors setup is a common silent failure causing CORS errors that are hard to diagnose.
When NOT to use
Avoid using overly permissive CORS settings like origins '*' in production. Instead, use strict origin lists or token-based authentication. For internal microservices, consider private networks or VPNs instead of CORS. If you need fine-grained access control, combine CORS with OAuth or API keys.
Production Patterns
In production, teams often configure CORS per environment, allowing localhost and staging domains during development but restricting to exact domains in production. They also monitor CORS errors via logging and browser reports. Some use environment variables to manage allowed origins dynamically without code changes.
Connections
HTTP Headers
CORS relies on specific HTTP headers to communicate permissions between server and browser.
Understanding HTTP headers like Origin and Access-Control-Allow-Origin clarifies how CORS controls cross-site requests.
Web Security Policies
CORS is part of a broader set of browser security policies including Content Security Policy and Same-Origin Policy.
Knowing CORS in context helps grasp how browsers protect users and how developers can safely share resources.
Access Control in Operating Systems
Both CORS and OS access control manage who can access resources, using rules and permissions.
Seeing CORS as a form of access control helps understand its role in protecting resources from unauthorized access.
Common Pitfalls
#1Allowing all origins with '*' in production including credentialed requests.
Wrong approach:Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do origins '*' resource '*', headers: :any, methods: [:get, :post], credentials: true end end
Correct approach:Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do origins 'https://trustedsite.com' resource '*', headers: :any, methods: [:get, :post], credentials: true end end
Root cause:Misunderstanding that '*' cannot be used with credentials in CORS, leading to broken authenticated requests.
#2Configuring rack-cors too late in middleware stack causing headers not to be set.
Wrong approach:Rails.application.config.middleware.use Rack::Cors do allow do origins 'https://example.com' resource '*', headers: :any, methods: [:get] end end
Correct approach:Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do origins 'https://example.com' resource '*', headers: :any, methods: [:get] end end
Root cause:Using 'use' instead of 'insert_before 0' places middleware too late, so CORS headers are not added in time.
#3Ignoring preflight OPTIONS requests causing 404 errors.
Wrong approach:Not handling OPTIONS requests in routes or middleware, leading to errors when browser sends preflight.
Correct approach:rack-cors middleware automatically handles OPTIONS requests if configured properly, no extra routes needed.
Root cause:Not understanding that browsers send OPTIONS preflight requests and that middleware must respond correctly.
Key Takeaways
CORS configuration in Rails controls which external websites can access your app's data through browser-enforced rules.
rack-cors middleware is the standard way to set CORS policies in Rails, and it must be configured early in the middleware stack.
Preflight OPTIONS requests are a key part of CORS and must be handled correctly to allow complex cross-origin requests.
Security is critical: avoid using wildcard origins with credentials and always specify trusted domains in production.
Understanding CORS deeply helps prevent common bugs and security issues when building APIs and frontend-backend integrations.