0

Consider the following scenario:

1) WebSocket authenticates the connection.

def connect
  self.current_user = find_verified_user
  logger.add_tags "ActionCable", "User #{current_user.id}"
end

2) When connection is established, inform the user

  connected: ->
    $("body").append("<div class='connection ok'>Connected.</div>")

3) When connection is lost, inform the user

  disconnected: ->
    $("pop-up").append("<div class='connection'>Offline, trying to reconnect...</div>")

4) When user logs out.....

An unauthorized connection attempt was rejected
###User is now informed connection is lost. Which should not happen.

My question: How can I change:

  mount ActionCable.server => '/cable'

To only work within the scope of:

 authenticated :user do
   root 'users#index', as: :authenticated_root
 end
Crashtor
  • 1,249
  • 1
  • 13
  • 21
  • 1
    "An unauthorized connection attempt was rejected" happens because most likely your `find_verified_user` has a code: `reject_unauthorized_connection unless current_user`. This may be either intentional or not: that is, do you allow non-signed-in users to also subscribe to the channel? Then you'll need to remove `reject_unauthorized_connection`. This will leave `current_user` to become `nil` if signedout; if you wish to still identify the current user even if non-signed-in, you can also add another identifier: `identified_by: :session_id`, and you set it by `self.session_id = request.session.id` – Jay-Ar Polidario Jul 11 '17 at 11:51
  • Ahh.. That's why. I thought that it'd just automatically exclude current_user if non was found. Thanks. – Crashtor Jul 11 '17 at 12:50
  • no problem!! :D – Jay-Ar Polidario Jul 11 '17 at 12:51
  • You can wrap it up in an answer and I'll give it to you. I know it doesn't answer the question, but still – should be an accepted answer. – Crashtor Jul 11 '17 at 12:53
  • alright then :) – Jay-Ar Polidario Jul 11 '17 at 12:53

1 Answers1

1

Alternative Solution

An unauthorized connection attempt was rejected

...happens when reject_unauthorized_connection is called in your connection.rb.

  • This may be either intentional or not:

    • remove reject_unauthorized_connection if you want to allow non-signed-users to subscribe to the channel: current_user becomes nil

      • To be able to still identify the user, you can add another identifier (:session_id) :

        module ApplicationCable
          class Connection < ActionCable::Connection::Base
            identified_by :current_user
            identified_by :session_id
        
            def connect
              self.current_user = find_verified_user
              self.session_id = request.session.id
            end
        
            private
        
            def find_verified_user
              User.find_by(id: cookies.signed[:user_id])
            end
        # ...
        
      • You may want to write your own authorisation in your *_channel.rb instead of here in the connection.rb if you'll need further authorisation rules between guest and signed-in users.
    • retain reject_unauthorized_connection if you only want signed-in users to be able to subscribe to your channels.
Jay-Ar Polidario
  • 6,463
  • 14
  • 28