验证ActionCable连接

时间:2015-08-15 14:54:46

标签: ruby-on-rails ruby ruby-on-rails-5 actioncable

我找到了一个很棒的ActionCable宝石,这是SPA的一个很好的解决方案。

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

3 个答案:

答案 0 :(得分:6)

来自Readme

# 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
    end

    protected
      def find_verified_user
        if current_user = User.find(cookies.signed[:user_id])
          current_user
        else
          reject_unauthorized_connection
        end
      end
  end
end

所以看起来你可以在这里插入自己的find_verified_user逻辑。 reject_unauthorized_connection方法位于lib/action_cable/connection/authorization.rb以供参考。

来自Heroku

  

[authentication]可以通过各种方式完成,就像WebSockets一样   传递通常用于身份验证的标准HTTP标头。   这意味着您可以使用相同的身份验证机制   用于WebSocket连接上的Web视图。

     

由于您无法从JavaScript自定义WebSocket标头,因此您只能使用   从内容发送的“隐式”身份验证(即基本或cookie)   浏览器。此外,拥有处理的服务器是很常见的   WebSockets与处理“普通”HTTP的处理器完全分开   要求。这可能会使共享授权标头变得困难或   不可能的。

考虑到这一点,不仅仅使用普通的Web登录流来设置您的身份验证cookie,在身份验证步骤之后交付SPA,这可能是一个真正的痛苦,但希望这可以为您提供一些指示。

答案 1 :(得分:3)

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

注意:此envENV不同。

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

如果您还没有使用devise,那么这是另一种解决方案。前提条件是,您必须在user_id或类似内容中设置名为sessions_controller的已签名Cookie。 例如

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

答案 2 :(得分:-4)

解决方案是使用HTTP授权令牌。这很简单,广泛而且显而易见。 This article给了我很多帮助