I'm working on a new Rails 5 (RC1) app. I used AuthLogic for user authentication, and it works great as always, until I got to ActionCable.
#app/channels/application_cable/connection.rb
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = UserSession.find
end
end
end
I get the error: You must activate the Authlogic::Session::Base.controller with a controller object before creating objects
I tried:
Authlogic::Session::Base.controller = Authlogic::ControllerAdapters::RailsAdapter.new(self)
But that does not work because the Connection class is not a Controller.
I look at the AuthLogic code, but I can't figure out how to bypass its dependence on a controller object. I just need to load the user's session. Any thoughts?
I figured it out on my own. I feel it is sort of hacky, basically in my ApplicationController I set a secure cookie with the AuthLogic persistence_token, then I can read this token and manually load the user in ActionCable.
class ApplicationController < ActionController::Base
before_action :set_verify_cookie
def set_verify_cookie
#action cable needs a way outside of controller logic to lookup a user
return unless current_user
cookies.signed[:vvc] = current_user.persistence_token
end
end
#app/channels/connection.rb
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_verified_user
logger.add_tags 'ActionCable', self.current_user.username unless self.current_user.nil?
end
protected
def find_verified_user_or_guest
User.find_by(:persistence_token => cookies.signed[:vvc])
end
end
One potential gotch, the cookie needs to be cleared on logout or ActionCable will still find the user on subsequent page loads.
#app/controllers/user_sessions_controller.rb
class UserSessionsController < ApplicationController
def destroy
cookies.signed[:vvc] = nil
current_user_session.destroy
flash[:success] = "Logout successful!"
redirect_to root_url
end
end