Cross-Origin Resource Sharing (CORS) Issues and How to Solve Them
--
When developing an application, a common issue that developers run into is one involving CORS. This is an issue that is quite frustrating when it comes up — you’ve spent hours coding, testing, and cleaning up your code, only to find that CORS is blocking a request that your application depends on to run. Luckily, the issue is one that is well-documented and not too hard to fix.
What is CORS?
CORS stands for Cross-Origin Resource Sharing and it is a security policy that handles the way in which requests for resources from external origins are managed. The main purpose of CORS is to allow servers to control who is able to access their data, maintaining security and privacy. CORS allows servers to specify which origins can make requests for their assets as well as what type of requests (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS) they are allowed to make.
Generally, most servers will allow GET requests from all origins so that their assets are widely available. To preserve the security of their assets, however, most servers will restrict other requests. To allow other types of HTTP requests, the server has to explicitly specify so.
CORS comes into play quite often in web development. Think about how often an application makes a request for images, scripts, fonts, stylesheets, or other data from an external API. Without CORS, we would not be able to load or share these resources, making the web a much less accessible and useful tool.
Request and Response Headers
The way in which CORS handles requests and responses involves HTTP headers. HTTP headers are chunks of data describing a request or response. These headers are passed back and forth between the client and server, allowing them to communicate a request and how the server responds to the request.
There are a bunch of headers available, which you can learn more about on MDN. For our purposes, the most relevant ones are the Access-Control-Allow-Origin and Access-Control-Allow-Methods.
Access-Control-Allow-Origin
: allows the server to specify which origins are allowed to access its resourcesAccess-Control-Allow-Methods
: allows the server to specify which HTTP methods are allowed when making a request for the resource
CORS Pre-Flight Requests
For requests such as DELETE, PUT, or PATCH, CORS makes use of something called pre-flight requests, which allows the browser to send a preliminary request to the server to check which origins and methods are allowed by the server before the actual request is sent. This pre-flight request involves an OPTION request. The server can then respond in two ways:
- allowing the request — the browser will then send the actual request to the server
- denying the request — the browser will then return an error to the client without having sent the request
Fixing CORS issues
Depending on what language or framework you are using for your backend and frontend, resolving CORS issues will look a little different. The main idea is that on the server-side, you’ll want to make sure that you specify which origins and methods are allowed for which resources.
If your backend is built on Ruby on Rails, the rack-cors gem is a highly useful tool. It allows you to easily handle CORS. To install the gem, you would run gem install rack-cors
or include gem ‘rack-cors’
in your Gemfile (don’t forget to run bundle install
after if using the latter method).
Then, in config/initializers/cors.rb
, you can include your specifications as to which origins, resources, headers, and methods to allow. An example is below: