window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(function () { var w = window if (w.LeadBooster) { console.warn('LeadBooster already exists') } else { w.LeadBooster = { q: [], on: function (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: function (n) { this.q.push({ t: 't', n: n }) }, } } })() Rails API & CORS. A dash of consciousness - The Codest
The Codest
  • About us
  • Services
    • Software Development
      • Frontend Development
      • Backend Development
    • Staff Augmentation
      • Frontend Developers
      • Backend Developers
      • Data Engineers
      • Cloud Engineers
      • QA Engineers
      • Other
    • It Advisory
      • Audit & Consulting
  • Industries
    • Fintech & Banking
    • E-commerce
    • Adtech
    • Healthtech
    • Manufacturing
    • Logistics
    • Automotive
    • IOT
  • Value for
    • CEO
    • CTO
    • Delivery Manager
  • Our team
  • Case Studies
  • Know How
    • Blog
    • Meetups
    • Webinars
    • Resources
Careers Get in touch
  • About us
  • Services
    • Software Development
      • Frontend Development
      • Backend Development
    • Staff Augmentation
      • Frontend Developers
      • Backend Developers
      • Data Engineers
      • Cloud Engineers
      • QA Engineers
      • Other
    • It Advisory
      • Audit & Consulting
  • Value for
    • CEO
    • CTO
    • Delivery Manager
  • Our team
  • Case Studies
  • Know How
    • Blog
    • Meetups
    • Webinars
    • Resources
Careers Get in touch
Back arrow GO BACK
2021-04-01
Software Development

Rails API & CORS. A dash of consciousness

The Codest

Krzysztof Buszewicz

Senior Software Engineer

For an experienced developer, this text may not be surprising at all, but I think that plenty of articles I’ve read about the CORS setup in Rails were saying something like: use rack-cors, allow any host to access the API, and (optionally): you should consider something different (than allowing any host) in production.

The proposed code was always close to the one below:

config/initializers/cors.rb

Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins ''
resource '', headers: :any, methods: :any
end
end

and, unfortunately, these texts were hardly explaining to us what to actually do in production.

I’m pretty OK with copy-pasting (I’m sometimes joking that companies could hire a Stack Overflow copy-paster), as far as there’s a “think and adjust” moment between “copy” and “paste”. So, I’d like to elaborate a little bit on what we’re doing here and how it works in real life.

I hope you don’t mind me starting with a short introduction to honor theory and then passing on to the Rails examples.

Introduction

Let’s start from the beginning. To explain things better, I’ve split the introduction into three parts. The first part will outline what’s an origin – the key term for what we are discussing here. The second is about SOP, just a short description. And the last part speaks about the CORS itself.

What is an origin?

According to the MDN Web Docs:

– Web content’s origin is defined by the scheme (protocol), host (domain), and port of the URL used to access it. Two objects have the same origin only when the scheme, host, and port all match (source)

That seems pretty clear, doesn’t it? Let’s analyze two examples from MDN, just in case.

  1. http://example.com/app1/index.html, http://example.com/app2/index.html

The 2 above have the same origin because:

  • their schemes (http) are the same,
  • their domains (example.com) are the same,
  • their ports (implicit) are the same.
  1. http://www.example.com, http://myapp.example.com

These 2 have different origin because the domains (www.example.com, myapp.example.com) are different.

I hope it’s clear enough. If not, please go to the MDN Web Docs for more examples.

What is SOP?

MDN Web Docs say (source):

– The same-origin policy is a critical security mechanism that restricts how a document or script loaded from one origin can interact with a resource from another origin. It helps isolate potentially malicious documents, reducing possible attack vectors.

– Cross-origin writes are typically allowed. Examples are links, redirects, and form submissions.

– Cross-origin embedding is typically allowed.

– Cross-origin reads are typically disallowed, but read access is often leaked by embedding.
Use CORS to allow cross-origin access

Well, as you can see, there is a lot about cross-origin behavior in the definitions of SOP. That’s ok. All we should know now is that the same origin has more privileges and we can loosen the rules for cross-origins by using CORS. And here the next section comes in.

What is CORS?

Basing on MDN’s words:

  • Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any other origins (domain, scheme, or port) than its own from which a browser should permit loading of resources. CORS also relies on a mechanism by which browsers make a “preflight” request to the server hosting the cross-origin resource, in order to check that the server will permit the actual request. In that preflight, the browser sends headers that indicate the HTTP method and headers that will be used in the actual request (source).

That’s still not enough. What was not said there explicitly is that the most important header when using CORS is Access-Control-Allow-Origin:

  • The Access-Control-Allow-Origin response header indicates whether the response can be shared with requesting code from the given origin (source).

Well, that should be it. In real life, when configuring CORS, we typically configure the ACAO header first.

Real Life

That’s it when it comes to definitions. Let’s circle back to Rails and real-life examples.

How to configure CORS in Rails?

We will definitely use rack-cors (like we were told to). Let’s recall the first snippet, the one that is most often provided in other articles:


config/initializers/cors.rb

Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins ''
resource '', headers: :any, methods: :any
end
end

The number of options is vast or even infinite but let’s consider those two:

  • we’re building the API that is allowed to be used by third party browser clients,
  • we’ve typical frontend/backend separation and want to allow our trusted clients to access the API.

Building API accessed by third party clients

If you’re facing the first option, you probably could go with origins ‘*’ – you want others to build a client on the top of your API, and don’t know who they are, right?

Typical frontend/backend separation

If you are developing the latter, you probably don’t want everyone to make cross-origin requests to your API. You rather want to:

  • allow production clients to access production API,
  • same for staging,
  • same for localhost,
  • you may want to allow FE review apps to access staging.

We will be still using rack-cors (like we were told to) – but our way.

Let’s use 2 ENV variables: ALLOWED_ORIGINS for literal origin definitions (an asterisk or actual URL) and ALLOWED_ORIGIN_REGEXPS for the patterns.

config/initializers/cors.rb

frozenstringliteral: true

toregexp = ->(string) { Regexp.new(string) }
hosts = [
*ENV.fetch('ALLOWEDORIGINS').split(','),
*ENV.fetch('ALLOWEDORIGINREGEXPS').split(';').map(&to_regexp)
]

Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins(*hosts)

resource '*',
         methods: %i[get post put patch delete options head],
         headers: :any

end
end

What’s going on here?

  1. As you can see, we’re splitting the values defined in ENV variables with different separators. That’s because a semicolon is less likely to appear in the URL defining pattern.
  2. Literal values are ready for use, but we have to map the patterns to be actual Regexp instances.
  3. Then, we’re joining everything together and allowing these hosts to access any resource with whitelisted methods our API uses.

This should give you enough flexibility to define proper values in your development, staging and production environments.

Conclusions

Let’s sum up all of the above in key points:

  • use ENV variables to configure CORS,
  • use regular expressions to allow different origins to access staging API (e.g., for review apps),
  • always put “think and adjust” between “copy” and “paste”.

That’s it. Have a nice day! 🙂

Read more:

Why you should (probably) use Typescript?

10 NYC Startups worth mentioning in 2021

Related articles

Software Development

Build Future-Proof Web Apps: Insights from The Codest’s Expert Team

Discover how The Codest excels in creating scalable, interactive web applications with cutting-edge technologies, delivering seamless user experiences across all platforms. Learn how our expertise drives digital transformation and business...

THECODEST
Software Development

Top 10 Latvia-Based Software Development Companies

Learn about Latvia's top software development companies and their innovative solutions in our latest article. Discover how these tech leaders can help elevate your business.

thecodest
Enterprise & Scaleups Solutions

Java Software Development Essentials: A Guide to Outsourcing Successfully

Explore this essential guide on successfully outsourcing Java software development to enhance efficiency, access expertise, and drive project success with The Codest.

thecodest
Software Development

The Ultimate Guide to Outsourcing in Poland

The surge in outsourcing in Poland is driven by economic, educational, and technological advancements, fostering IT growth and a business-friendly climate.

TheCodest
Enterprise & Scaleups Solutions

The Complete Guide to IT Audit Tools and Techniques

IT audits ensure secure, efficient, and compliant systems. Learn more about their importance by reading the full article.

The Codest
Jakub Jakubowicz CTO & Co-Founder

Subscribe to our knowledge base and stay up to date on the expertise from the IT sector.

    About us

    The Codest – International software development company with tech hubs in Poland.

    United Kingdom - Headquarters

    • Office 303B, 182-184 High Street North E6 2JA
      London, England

    Poland - Local Tech Hubs

    • Fabryczna Office Park, Aleja
      Pokoju 18, 31-564 Kraków
    • Brain Embassy, Konstruktorska
      11, 02-673 Warsaw, Poland

      The Codest

    • Home
    • About us
    • Services
    • Case Studies
    • Know How
    • Careers
    • Dictionary

      Services

    • It Advisory
    • Software Development
    • Backend Development
    • Frontend Development
    • Staff Augmentation
    • Backend Developers
    • Cloud Engineers
    • Data Engineers
    • Other
    • QA Engineers

      Resources

    • Facts and Myths about Cooperating with External Software Development Partner
    • From the USA to Europe: Why do American startups decide to relocate to Europe
    • Tech Offshore Development Hubs Comparison: Tech Offshore Europe (Poland), ASEAN (Philippines), Eurasia (Turkey)
    • What are the top CTOs and CIOs Challenges?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Website terms of use

    Copyright © 2025 by The Codest. All rights reserved.

    en_USEnglish
    de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish arArabic it_ITItalian jaJapanese ko_KRKorean es_ESSpanish nl_NLDutch etEstonian elGreek en_USEnglish