I am trying to implement a chat widget that can be embedded in any website and for that I decided to use MessageBus to communicate between the widget and my Rails backend. Since it can be embedded in any origin I needed to deal with cross origin requests.
However I want to enable CORS only for message bus requests and not all my other routes. I already saw this issue CORS configuration · Issue #135 · discourse/message_bus · GitHub
That’s what I did in my config/initializers/cors.rb
.
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*', headers: :any, methods: [:get, :post, :put, :patch, :delete, :options]
end
end
It works but this allows the cross origin requests for any route which is not what I want.
I also tried to do my own middleware
# app/middleware/message_bus_cors_middleware.rb
class MessageBusCorsMiddleware
def initialize(app)
@app = app
end
def call(env)
# If it's message bus and an OPTIONS request, return CORS headers
if env['PATH_INFO'].start_with?('/message-bus') && env['REQUEST_METHOD'] == 'OPTIONS'
# Apply CORS headers for /message-bus requests
headers = {
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => 'GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD',
'Access-Control-Allow-Headers' => 'Origin, X-Requested-With, Content-Type, Accept, Authorization, X-Visitor-Token',
'Access-Control-Max-Age' => '86400'
}
[200, headers, []]
else
@app.call(env)
end
end
end
But I still have cross origin issues with this middleware.
Any other idea ?
Another thing that would be great is to enable cross origin only for specific channels. ( In my case the chat message bus channels). In did I use MessageBus in other parts of my application that do not do cross origin requests and I would like to keep it like that.