Rails5 ActionCable include current_user method from SessionsHelper - ruby-on-rails

I want to get access to my current_user method which is defined in the SessionsHelper. How can I include or require it for the ApplicationCable Connection class?
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
if current_user
self.current_user = current_user
logger.add_tags current_user.name
end
end
end
end
gives me
There was an exception - NoMethodError(undefined method `name' for nil:NilClass)
Equivalent to the ApplicationController I included the SessionHelper in channels/application_cable/connection.rb
module ApplicationCable
class Connection < ActionCable::Connection::Base
include SessionsHelper
identified_by :current_user
# (..)
end
end
but doesn't work.

As you can see in the notesof the official documentation the cable can not access the session. In this article, cited in the notes, you can find a way to use cookies for managing athentication

Related

Access env['warden'].user from ApplicationCable is nil

So I am trying to implement dervise-jwt in a Rails 5.2 application. My login is working properly, and the tokens are being created. That being said, I want to access that same current_user from my ActionCable. Following some online tutorials, my app/channels/application_cable/connection.rb looks like this:
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_verified_user
end
private
def find_verified_user
if user == env['warden'].user
user
else
reject_unauthorized_connection
end
end
end
end
When I debug the code, env['warden'].user is nil. What do I have to do to get the current_user accessible via warden?

How can I write unit tescase for action cable connection class in rails 6

following is my connection.rb
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_verified_user
end
private
def find_verified_user
verified_user = env['warden'].user
return verified_user if verified_user
end
end
end
How can I work on a unit test with the environment variable warden?
Do I need to set it?
after too much of search I have got the solution for connection_test.rb
# frozen_string_literal: true
require "test_helper"
module ApplicationCable
class ConnectionTest < ActionCable::Connection::TestCase
include ActionCable::TestHelper
test "connects with devise" do
user = users(:admin)
connect_with_user(user)
assert_equal connection.current_user, user
end
private
def connect_with_user(user)
connect env: { 'warden' => FakeEnv.new(user) }
end
class FakeEnv
attr_reader :user
def initialize(user)
#user = user
end
end
end
end

Making current_user available in ActionCable channels using bcrypt

I'm trying to make current_user available in my channel actions.. This is the first time I'm diving into ActionCable and the tutorial I'm following is using Devise and I am not..
In channels/application_cable/connection.rb. They have
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_verified_user
logger.add_tags 'ActionCable', current_user.email
end
protected
def find_verified_user # this checks whether a user is authenticated with devise
if verified_user = env['warden'].user
verified_user
else
reject_unauthorized_connection
end
end
end
end
I'm having trouble with the protected method. I'm not sure how to verify the user from this file using bcrypt.. Also the directory this file is under seems to be likened to helpers for ActionCable, am I correct in thinking this?

ActionCable does not run connect method upon connecting

I'm trying to work with ActionCable, but right now I'm trying to do the seemingly trivial task of trying to get a user id in a channel when I have the connection identified by current_user and its set properly in the connect method. I feel like I'm missing something completely obvious here. Here are my two relevant files
application_cable/connection.rb
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = env['warden'].user
end
end
end
notifications_channel.rb
class NotificationChannel < ApplicationCable::Channel
def subscribed
stream_from("push_notification_channel_#{connection.current_user.id}")
end
end
For some reason connection.current_user is nil in notifications channel. Am I just missing something really obvious?

Getting AuthLogic to work with ActionCable

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
Assuming you're using Authlogic default, the persistence token is stored in the cookie under the key 'user_credentials'.
So you can lookup your user like this:
# app/channels/application_cable/connection.rb
module ApplicationCable
class Connection < ActionCable::Connection::Base
def connect
verify_user
end
private
def verify_user
reject_unauthorized_connection unless verified_user?
end
def verified_user?
cookie_key && User.find_by_persistence_token(token)
end
def token
cookie && cookie.include?('::') && cookie.split("::")[0]
end
def cookie
cookies['user_credentials']
end
end
end

Resources