Ruby on rails 验证ActionCable连接

Ruby on rails 验证ActionCable连接,ruby-on-rails,ruby,ruby-on-rails-5,actioncable,Ruby On Rails,Ruby,Ruby On Rails 5,Actioncable,我发现了一个很棒的ActionCable gem,这是一个很好的SPA解决方案 我只想发送html、css和js资产,所有其他连接都将通过ActionCable实现。交换字符串或整数并不困难,但如何通过ActionCable登录 从 #app/channels/application_cable/connection.rb 模块可应用 类连接

我发现了一个很棒的ActionCable gem,这是一个很好的SPA解决方案

我只想发送
html
css
js
资产,所有其他连接都将通过
ActionCable
实现。交换字符串或整数并不困难,但如何通过ActionCable登录

#app/channels/application_cable/connection.rb
模块可应用
类连接
因此,看起来您可以在此处插入自己的
find\u verified\u user
逻辑。
reject\u unauthorized\u connection
方法位于
lib/action\u cable/connection/authorization.rb中,以供参考

发件人:

[authentication]可以通过多种方式进行,正如WebSocket所做的那样 传递通常用于身份验证的标准HTTP头。 这意味着您可以使用相同的身份验证机制 也可用于WebSocket连接上的web视图

由于无法从JavaScript自定义WebSocket头,因此只能使用 从服务器发送的“隐式”身份验证(即Basic或Cookie) 浏览器此外,通常有一个服务器来处理 WebSocket必须与处理“正常”HTTP的WebSocket完全分离 请求。这可能会使共享授权标头变得困难或无效 不可能


考虑到这一点,不只是使用普通的web登录流来设置身份验证cookie,在身份验证步骤之后交付SPA,这可能是一个真正的难题,但希望这能给您一些提示。

解决方案是使用HTTP授权令牌。这是简单的,广泛的和明显的。对我帮助很大

仅供参考,如果您的应用程序中已经安装了
设计
,那么您可以使用
管理员设置的环境变量来查找
经过身份验证的用户
。对于每个经过身份验证的用户,warden将用户对象存储在环境变量中。每个请求都由
warden
中间件进行身份验证

注意:这与
ENV
不同

module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user

    def connect
      self.current_user = find_verified_user_from_env
    end

    private
    def find_verified_user_from_env
      # extracting `user` from environment var
      current_user = env['warden'].user
      if current_user
        current_user
      else
        reject_unauthorized_connection
      end
    end
  end
end
和连接:

# app/channels/application_cable/connection.rb
module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user

    def connect
      self.current_user = find_verified_user_from_cookies
    end

    private
    def find_verified_user_from_cookies
      current_user = User.find_by_id(cookies.signed[:user_id])
      if current_user
        current_user
      else
        reject_unauthorized_connection
      end
    end
  end
end
#app/channels/application_cable/connection.rb
模块可应用
类连接
登录必须使用通常的Rails方式完成,您可以检查用户是否已通过此处所述的身份验证:我知道我可以做到这一点,但我需要所有站点通过WebSocket进行工作。我可以实现这个吗?
cookies.signed[:user_id] = current_user.id
# app/channels/application_cable/connection.rb
module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user

    def connect
      self.current_user = find_verified_user_from_cookies
    end

    private
    def find_verified_user_from_cookies
      current_user = User.find_by_id(cookies.signed[:user_id])
      if current_user
        current_user
      else
        reject_unauthorized_connection
      end
    end
  end
end