Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails Devise Action Cable

I'm trying to get Action Cable working with Devise.

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.name
    end

    protected

    def find_verified_user
      verified_user = User.find_by(id: cookies.signed['user.id'])
      if verified_user && cookies.signed['user.expires_at'] > Time.now
        verified_user
      else
        reject_unauthorized_connection
      end
    end
  end
end

If an user is logged in I still get nil from cookies.signed['user.id']

like image 220
markus_springer Avatar asked Jul 20 '16 00:07

markus_springer


People also ask

What is the use of action cable in rails?

1 What is Action Cable? Action Cable seamlessly integrates WebSockets with the rest of your Rails application. It allows for real-time features to be written in Ruby in the same style and form as the rest of your Rails application, while still being performant and scalable.

How do you test an action cable?

Testing Action Cable To test this connection class, we can use connect method to simulate a client server connection and then test the state of connection is as expected. The connection object is available in the test.

Does ActionCable use Redis?

ActionCable is backed by Redis Pub/Sub. Redis is one incredible piece of engineering which we use extensively in our Ably infrastructure.

What is AnyCable?

AnyCable allows you to use any WebSocket server (written in any language) as a replacement for your Ruby server (such as Faye, Action Cable, etc). AnyCable uses the same protocol as ActionCable, so you can use its JavaScript client without any monkey-patching.


2 Answers

Update your connection.rb with the following:

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.studentid
    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

Link: https://www.pluralsight.com/guides/implementing-a-custom-devise-sign-in-and-actioncable-rails-5

like image 196
Stockholmkid Avatar answered Oct 23 '22 07:10

Stockholmkid


Try setting the cookie in a warden callback.

Add a file to `config/initializers/your_file.rb``

Add this to the file:

Warden::Manager.after_set_user do |user, auth, opts|
  scope = opts[:scope]
  auth.cookies.signed["#{scope}.id"] = user.id
  auth.cookies.signed["#{scope}.expires_at"] = 60.minutes.from_now
end

Warden::Manager.before_logout do |user, auth, opts|
  scope = opts[:scope]
  auth.cookies.signed["#{scope}.id"] = nil
  auth.cookies.signed["#{scope}.expires_at"] = nil
end

Or you could do something like this:

verified_user = env['warden'].user

As explained in this very nice tuorial: https://www.sitepoint.com/create-a-chat-app-with-rails-5-actioncable-and-devise/

like image 39
LewisFidlers Avatar answered Oct 23 '22 06:10

LewisFidlers