How to Fix That Pesky CORS Error
This past week, I was working on building a new app. I had just finished setting up the React frontend and Rails API backend, but when I tried to make my first API request I came across an error I had never seen before:
I remembered learning about CORS the first time I built a Rails API. For anyone unfamiliar with it, here’s a quick breakdown:
CORS stands for “cross origin resource sharing.” It’s what allows web applications to make “cross-domain” requests under secure conditions. In other words, it gives scripts running on one browser permission to access resources from a different origin, hence the term “cross origin.”
What is an origin?
An origin refers to a URL’s:
· scheme or protocol (http://, https://)
· port (80, 81)
· host or domain name (example.com)
CORS, on the contrary, provides developers with more flexibility (albeit, less secure) so they can allow cross-origin requests and data transfers under predetermined conditions. So, in my case, I can make requests from my React frontend to my Rails API backend.
So, what about that error?
For starters, “Access-Control-Allow-Origin” is an HTTP response header that the server sends in response to an HTTP request. Its main job is to tell the browser whether or not it’s allowed to access a resource based on the origin of the request. The error message I received stated that no header was present, so the browser blocked the resource.
To resolve that, I decided to take a look at my CORS settings on the backend. When I first created the Rails API, I uncommented the “rack-cors” gem from my Gemfile and bundle installed. I then uncommented everything out in my cors.rb file. Take a look below and see if you can figure out what else needed to be changed.
Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do origins 'example.com' resource '*', headers: :any, methods: [:get, :post, :put, :patch, :delete, :options, :head] endend
As you can see above, my origins were set to allow “example.com” (essentially, nothing). “Origins” refer to the website(s) making a request. So I changed “example.com” to “*” because I wanted to allow any client to make a request, or all origins. And I didn’t need to specify the exact headers, since my middleware (rack-cors gem) took care of serving them for me. Then, I restarted my server, and voilà! All fixed.
Quick note: I could have strictly specified origins to only allow “localhost:3001,” which is the origin of my client-side app, but I chose all (“*”) because web fonts rely on CORS too. Since I was using a couple Google fonts, I wanted that flexibility. In the future when I decide to deploy my app, I’ll edit my cors.rb file to be a bit more specific (and secure) with whitelisted origins.
Cross-Origin Resource Sharing (CORS)
Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web…
The same-origin policy is a critical security mechanism that restricts how a document or script loaded from one origin…