4

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

我只想发送和资产html,所有其他连接都将通过. 交换字符串或整数并不难,但是如何通过 ActionCable 登录呢?cssjsActionCable

4

3 回答 3

6

来自自述文件

# 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

[身份验证] 可以通过多种方式完成,因为 WebSockets 将通过通常用于身份验证的标准 HTTP 标头。这意味着您也可以使用与 WebSocket 连接上的 Web 视图相同的身份验证机制。

由于您无法从 JavaScript 自定义 WebSocket 标头,因此您仅限于从浏览器发送的“隐式”身份验证(即 Basic 或 cookie)。此外,处理 WebSocket 的服务器与处理“正常”HTTP 请求的服务器完全分开是很常见的。这会使共享授权标头变得困难或不可能。

考虑到这一点,不只是使用普通的 Web 登录流程来设置您的身份验证 cookie、在身份验证步骤之后提供您的 SPA 可能会很痛苦,但希望这可以给您一些指导。

于 2015-08-25T14:47:20.667 回答
6

仅供参考,如果您devise已经在应用程序中安装,那么您可以使用设置的环境变量warden来查找authenticated user. 对于每个经过身份验证的用户,守望者将用户对象存储在环境变量中。每个请求都由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

如果您还没有使用过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
于 2017-05-15T02:39:55.017 回答
-8

解决方案是使用 HTTP 授权令牌。它简单、广泛且显而易见。这篇文章对我帮助很大

于 2015-09-02T16:44:05.203 回答