8

I have an issue with connection to web socket. There is an error:

Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" IS NULL LIMIT ?  [["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 2016-09-11 18:57:49 +0200
Finished "/cable/" [WebSocket] for 127.0.0.1 at 2016-09-11 18:57:49 +0200

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', "User #{current_user.id}"
    end

    protected

    def find_verified_user
      if verified_user = User.find_by(id: cookies.signed[:user_id])
        verified_user
      else
        reject_unauthorized_connection
      end
    end
  end
end

I found some solution that I should use config.allowed_request_origins, but it doesn't resolve my problem. I tried with session_helper by adding this method:

def set_cookie(user)
  the_username = user.username.to_s
  cookies.permanent.signed[:username] = the_username
end

Nothing repairs my problem.

Update: I saw that problem is that cookies.signed[:user_id] is nil. Have you any suggestions what can the cause of this? I use standard URL and port for tests(localhost:3000).

Prezes Łukasz
  • 938
  • 1
  • 9
  • 30
  • After seeing the same errors in my logs for the same issue, this SO post helped me solve my problem. https://stackoverflow.com/questions/38719359/action-cable-not-working-after-binding-with-ip?rq=1. Just need to set `config.action_cable.allowed_request_origins` in `config/environments/development.rb` with the hosts that you will allow to connect to your app via websockets. – ethaning Mar 17 '21 at 10:26

2 Answers2

5

I resolved my problem by using env['warden'].user. Below is updated method.

   def find_verified_user
      (current_user = env['warden'].user) ? current_user : reject_unauthorized_connection
   end
Prezes Łukasz
  • 938
  • 1
  • 9
  • 30
  • 5
    This is not enough. This way you just removed the error when a user is logged in. But if the user is not logged in - the **error persists**. This is because of the `App.room = App.cable.subscriptions.create "RoomChannel"` call `inside room.coffee` (or like that in your code). The solution would be to conditionally render `room.coffee` depending on whether a user is logged in or not - but that would require excluding `room.coffee` from assets - and its separate rendering (because you can't conditionally render js if a user is logged in/out). – prograils Apr 04 '17 at 12:14
1

Before doing any changes to your code just stop the rails server and do bundle install then restart.May be that issue will get resolved.