I'm having trouble setting up CORS with my Rails API in CloudAnywhere.
I am trying to set up a React front end and a Rails back end in two separate CloudAnywhere containers. (Let's call them rails.codeanyapp.com and react.codeanyapp.com.)
The React front end is set up with a proxy to Rails (i.e., "proxy": "https://rails.codeanyapp.com" in package.json).
The Rails back end has the following code in config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins 'https://react.codeanyapp.com/'
resource '*',
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :options, :head]
end
end
GET requests work fine. However, when I do a POST, I get the following error in Rails
Started POST "/authors.json" for 104.42.117.130 at 2019-03-19 13:05:52 -0400
Cannot render console from 104.42.117.130! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by AuthorsController#create as JSON
Parameters: {"fname"=>"James", "lname"=>"madison", "email"=>"[email protected]", "author"=>{"fname"=>"James", "lname"=>"madison", "email"=>"[email protected]"}}
HTTP Origin header (https://rails.codeanyapp.com) didn't match request.base_url (https://react.codeanyapp.com)
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms)
Notice that CodeAnywhere is set up so the public URL is https://rails.codeanyapp.com even though the server is actually running on port 3000. I suspect the issue is on the Rails side when the incoming port is "forwarded" to 3000; but, I don't think I have privileges to modify that behavior.
Notice also that both the Origin and the base are https. (Most other posts about this problem are when one is http and the other is https.)
The main problem is that I got lazy and tried to simply throw
jsonrendering into an existing controller. (Specifically, I added arespond_toblock to an existing controller that is a subclass ofApplicationController.) The problem with this is that, by default, Rails adds CSRF and other middleware that doesn't apply as cleanly to an API.The correct solution is to create a separate controller that inherits from
ApplicationController::APICombining API and web views in Rails 5The quick and dirty solution was to turn off CSRF for API calls by adding
protect_from_forgery unless: -> { request.format.json? }toapplication_controller.rb