如何使用Pundit与Actioncable(Rails 5)

时间:2017-05-23 19:25:51

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

我想知道如何通过rails5中的通道限制与频道的连接或消息流。目前,我与使用pundit的组中的用户进行分组,并且与该websocket的连接发生在该组内。如果恶意用户随机猜到了他们可能通过套接字读取消息,他们就不应该这样做。

创建新邮件时,我的控制器中会运行以下代码:

if message.save
  ActionCable.server.broadcast "messages_#{message.groupchat_id}_channel",
    message: message.content,
    user: message.user.email
  head :ok
end

我不知道我在做什么。

2 个答案:

答案 0 :(得分:0)

这是我发现将Pundit与Activecable结合使用的解决方案。

首先,我们需要访问用户模型。您可以按照Action Cable Overview - Connection Setup中的说明进行操作。主要是您需要更改connection.rb中的代码

# 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

    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

注意:您可能需要使用其他方式来找到您的用户。我正在使用devise_token_auth,因此需要将uid,令牌和client_id传递给connection.rb,然后通过此代码吸引用户:

if user && user.valid_token?(token, client_id)
  user
else
  reject_unauthorized_connection
end

我之所以这样说,是因为您获得用户的方式可能有所不同。最主要的是,您需要使用current_user的identified_by进行设置。

我在文档中没有立即发现的另一件事是,您的频道现在可以访问current_user。由于用户名可能与您的pundit_user名称不同,因此我发现此时手动将用户传递给Pundit最简单。因此,在订阅频道文件时,我有以下代码:

  def subscribed
    message = MessagePolicy::Scope.new(self.current_user, Project).resolve.find(params[:message])
    stream_for message
  end

您当然也可以手动授权,而不用使用Scope:

MessagePolicy.new(self.current_user, message).show?

答案 1 :(得分:-1)

您可以在app / channels / application_cable / connection.rb文件中为actioncable连接添加另一层安全保障。

您可以按照本教程操作。我想这会给你一些想法: https://www.learnenough.com/action-cable-tutorial#sec-login_protection