Lesson Tuesday

If we want to make our API available to other users, specifically those that will call this API with JavaScript in the browser, we must enable something called CORS (cross-origin resource sharing) requests. Browsers implement something called the same-origin policy, a security measure that requires resources come from the same domain. But CORS is a protocol that allows browsers to communicate across different domains.

In our JavaScript course, we focused on APIs that allow CORS requests. Our JavaScript applications, which made API calls from the browser, couldn't interact with applications that don't allow CORS because of the same-origin policy. We were trying to send a request to a different domain so we had to use a hacky Chrome plug-in to get around this issue for APIs that didn’t use CORS.

Now that we're building our own Rails APIs, we can decide whether we'll allow CORS requests or not. If we want to allow all sources to communicate with our API, we'll need CORS. On the other hand, if our application should only handle requests made by other server-side applications, we might choose to handle CORS requests differently (or not have them at all).

We can configure CORS in app/config/initializers. Initializers are run after an application's environment is loaded and are responsible for a number of tasks, including building our application's middleware. Our Rails application automatically uses rack-cors middleware to handle CORS. (A quick reminder: middleware acts as a bridge between our application and the server running our application; Rails is built on Rack middleware.)

Let's take a look at the CORS initializer now. You'll see the following commented-out code:

config/initializers/cors.rb
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]
  end
end

This code is boilerplate for allowing CORS requests. Let's go over a few key points.

First, we can specify which origins we'll allow. For instance, if we change example.com to the wild card *, our application will allow all origins. (This is potentially very risky, since it makes our application much more insecure!) We can also choose to limit origins to a single domain, such as the domain where our client-side application is being hosted (if it's a different domain from the server).

In addition, we can limit which resources are made available to these origins (in this case, the wild card * means all resources are allowed) as well as which headers and methods we'll accept. For instance, we could provide only the [:get] method if we don't want other applications to post or otherwise make changes to our database.

If you leave the code in the cors.rb file commented-out, your application will not allow CORS. If the code isn't commented out, your API will allow CORS to the origins you specify.

One other thing: Rails relies on the gem rack-cors for CORS configuration. If you modify your cors.rb file to use it but don't have this gem bundled, you'll get an uninitialized constant error. The gem is automatically included in the Gemfile of a Rails project; however, it's commented out. Uncomment the line gem 'rack-cors' in your Gemfile and then bundle. Then you can update your CORS settings. (If you make any alterations to cors.rb, you'll need to restart the server to ensure that changes take effect.)

Now that you know how CORS is configured in a Rails application, you can explore further customization on your own or simply leave it commented out. You don't need to allow CORS to make requests from Postman, cURL or another Rails application, and you won't be expected to configure CORS settings on your code review. However, if you try to make a request to your API from the browser with JavaScript, you’ll need to enable CORS.

Lesson 15 of 19
Last updated more than 3 months ago.