Rails Action Cable: Как авторизовать входящее соединение? - PullRequest
0 голосов
/ 07 октября 2018

Я пытаюсь реализовать авторизацию для соединения через веб-сокет (rails 5.2.1)

Следуя указаниям rubyonrails , я создал файл connection.rb следующим образом:

# app / channel / application_cable / 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
        if verified_user = User.find_by(id: cookies.encrypted[:user_id])
          verified_user
        else
          reject_unauthorized_connection
        end
      end
  end
end

К сожалению, все запросы на подключение к веб-сокету отклоняются.(Я выяснил, что cookies.encrypted [: user_id] возвращает nil.)

Started GET "/cable" for ::1 at 2018-10-07 21:33:46 +0300
Started GET "/cable/" [WebSocket] for ::1 at 2018-10-07 21:33:46 +0300
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
  User Load (0.5ms)  SELECT  "users".* FROM "users" WHERE "users"."is_active" = $1 AND "users"."id" IS NULL LIMIT $2  [["is_active", true], ["LIMIT", 1]]
  ↳ app/channels/application_cable/connection.rb:12
An unauthorized connection attempt was rejected
Failed to upgrade to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
Finished "/cable/" [WebSocket] for ::1 at 2018-10-07 21:33:46 +0300
Finished "/cable/" [WebSocket] for ::1 at 2018-10-07 21:33:46 +0300

Не могли бы вы мне подсказать, как я могу получить доступ к информации о текущем пользователе в app / channel / application_cable / connection.rb?

1 Ответ

0 голосов
/ 07 октября 2018

Чтобы получить current_user от Devise, вам нужно изменить 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', 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
...