问题
I'm building a SaaS platform with the apartment gem and am introducing ActionCable for chat functionality. I have most of the chat functionality built, but when transmitting to the channel I get the following:
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
An unauthorized connection attempt was rejected
Failed to upgrade to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
Finished "/cable/" [WebSocket] for 127.0.0.1 at 2017-02-01 08:49:53 -0600
Finished "/cable/" [WebSocket] for 127.0.0.1 at 2017-02-01 08:49:53 -0600
I'm using this code in app/channels/connection.rb
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_verified_user
tenant = request.subdomain
Apartment::Tenant.switch!(tenant)
logger.add_tags "ActionCable", "User #{current_user.id}", "Tenant #{tenant}"
end
protected
def find_verified_user
if current_user = env['warden'].user
current_user
else
reject_unauthorized_connection
end
end
end
end
This in theory should switch the Tenant and get Actioncable transmitting on the right subdomain. But I'm still getting these errors.
I'm also using Devise and am logged in as a user so there's no reason that I can think of why the connection was rejected since it's looking up the current user and validating that the user is a logged in devise user based off of the warden ENV.
I'm wondering since I have subdomains in play if I should be configuring the request origins in a certain fashion.
To test this I hardcoded one of my subdomains that I'm using on the lvh.me localhost domain as such:
Rails.application.config.action_cable.allowed_request_origins = ['http://acme.lvh.me:3000']
I was wondering if the allowed_request_origins has something to do with this and if so, how can I use regex to allow for any subdomain to the lvh.me:3000 url/domainspace?
Help is greatly appreciated.
回答1:
With the help of a friend we learned that we needed to switch tenants prior to establishing the connection. Here is the connection.rb
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
tenant = request.subdomain
Apartment::Tenant.switch!(tenant)
self.current_user = find_verified_user
logger.add_tags "ActionCable", "User #{current_user.id}", "Tenant #{tenant}"
end
protected
def find_verified_user
if current_user = env['warden'].user
current_user
else
reject_unauthorized_connection
end
end
end
end
To handle the regex portion in development.rb to handle the request origins I did this:
Rails.application.config.action_cable.allowed_request_origins = ['http:\/\/*.lvh.me:3000*']
So far it's working and AC is transmitting properly with Apartment on subdomains. At least in development.
来源:https://stackoverflow.com/questions/41982812/rails-actioncable-request-origins-subdomain