Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails:Action Cable:如何根据角色授权用户连接特定通道?_Ruby On Rails_Actioncable - Fatal编程技术网

Ruby on rails Rails:Action Cable:如何根据角色授权用户连接特定通道?

Ruby on rails Rails:Action Cable:如何根据角色授权用户连接特定通道?,ruby-on-rails,actioncable,Ruby On Rails,Actioncable,在我的rails拍卖应用程序中,授权用户可以在产品页面内同时连接到2个频道(一个是产品的all_users频道,另一个是直接消息的用户特定频道) 现在我只想将敏感信息发送给管理员组用户。我想我可以在coffee脚本中定义第三个通道连接请求(admin_channel),但我不知道如何根据角色授权第三个通道的用户连接 另一种选择可能是利用现有的特定于用户的通道,但在这里,我无法理解后端类如何知道管理组中的哪些用户当前处于联机状态(已启动并运行用户通道) 你知道我怎样才能做到吗?任何形式的支持都将不

在我的rails拍卖应用程序中,授权用户可以在产品页面内同时连接到2个频道(一个是产品的all_users频道,另一个是直接消息的用户特定频道)

现在我只想将敏感信息发送给管理员组用户。我想我可以在coffee脚本中定义第三个通道连接请求(admin_channel),但我不知道如何根据角色授权第三个通道的用户连接

另一种选择可能是利用现有的特定于用户的通道,但在这里,我无法理解后端类如何知道管理组中的哪些用户当前处于联机状态(已启动并运行用户通道)

你知道我怎样才能做到吗?任何形式的支持都将不胜感激

在下面,您可以找到我现有的connection.rb文件和coffeescript文件

这是我的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 # 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
私人管理信息频道.rb

class PrivateAdminMessagesChannel < ActionCable::Channel::Base
  def subscribed    
    stream_from :private_admin_messages_channel, coder: ActiveSupport::JSON do |data|
      from_user = User.find(data.fetch('from_user_id'))
      to_user = User.find(data['to_user_id']) if data['to_user_id']
      message = data.fetch('message')

      # authorize if "message" is sent to you (a non-admin), and also
      # authorize if "message" is sent to you (an admin)

      if (to_user && to_user == current_user) || (!to_user && current_user.is_admin?)
        # now, finally send the Hash data below and transmit it to the client to be received in the JS-side "received(data)" callback
        transmit(
          from_user_id: from_user.id,
          to_user_id: to_user&.id,
          message: message
        )
      end
    end
  end

  def send_message_to_admins(data)
    ActionCable.server.broadcast 'private_admin_messages_channel', 
      from_user_id: current_user.id,
      message: data.fetch('message')
  end

  def send_message_to_user_and_admins(data)
    from_user = current_user

    reject unless from_user.is_admin?

    ActionCable.server.broadcast 'private_admin_messages_channel', 
      from_user_id: from_user.id,
      to_user_id: data.fetch('to_user_id'),
      message: data.fetch('message')
  end
end
class privateAdminingMessageSchannel
以上是我能想到的最简单的方法。不是最有效的,因为每个流都有一个额外的授权级别(请参见块中的
stream_),不同于我们有不同的广播名称,授权只在“连接”本身上发生一次,而不是在每个“流”。。。这可以通过以下方式实现:

  • Admin User1打开页面,然后JS订阅
    UserConnectedChannel
  • 非管理员用户2打开页面,然后JS订阅
    privateAdminMessagesAnnel
    传入数据:
    user\u id:CURRENT\u user\u id
  • 从2。如上所述,因为User2刚刚订阅;然后在后端,在连接后的
    def subscribed
    内,您
    ActionCable.server.broadcast:user\u connected,{user\u id:current\u user.id}
  • 订阅了
    UserConnectedChannel
    的Admin User1然后接收带有
    数据{user\u id:THAT\u USER2\u id}
  • 从上面的第4步开始,在JS
    received(data)
    callback中,现在JS订阅
    privateAdminingMessagesAnnel
    传入数据:该用户2\u id`
  • 现在User1和User2都订阅了
    privateAdminMessagesAnnel user\u id:THAT\u User2\u id
    ,这意味着他们可以私下交谈(其他管理员也应该已经收到
    :user\u connected
    的JS数据:
    {user\u id:THAT\u User2\u id}
    ,因此它们也应该订阅,因为AdminUser1、NonAdminUser2和AdminUser3可以在同一个聊天频道中聊天……这是我根据您的要求得到的)
  • TODO:从上面的1到6,对“断开连接”过程也执行类似的操作
  • 琐事:
    • 可以在频道文件中访问您在
      ApplicationTable::Connection
      中定义的由
      标识的
      。特别是,在这种情况下,可以调用当前用户
    • 关于拒绝订阅,请参阅

    它们是否连接到同一频道
    MyauctionChannel
    ?但它们连接到不同的房间,正如您的
    id:$(''uuid').attr('data-id')
    所标识的,而另一个是
    id:$('uuid').attr('data-uuid-code')
    ?@Jay Ar Polidario我试图对这个问题进行更多的澄清。。正如您所指出的,用户连接到基于产品的“广播”频道$('#auctionID').attr('data-uuid-code')以及用户特定频道。我还没有测试过这一点,因此我可能错过了一些东西;让我知道accordingly@Tolga不用担心,祝你好运!:)
    $(document).ready ->
        App.privateAdminMesssagesChannel = App.cable.subscriptions.create({
            channel: 'PrivateAdminMessagesChannel'
          },
          connected: ->
          disconnected: ->
          // call this function to send a message from a Non-Admin to All Admins
          sendMessageToAdmins: (message) ->
            @perform 'send_messsage_to_admins', message: message
          // call this function to send a messsage from an Admin to (a Non-admin + all Admins)
          sendMessageToUserAndAdmins: (message, toUserId) ->
            @perform 'send_messsage_to_user_and_admins', message: message, to_user_id: toUserId
    
          received: (data) ->
            console.log(data.from_user_id)
            console.log(data.to_user_id)
            console.log(data.message)
    
            if data.to_user_id
              // this means the message was sent from an Admin to (a Non-admin + all admins)
            else
              // this means the message was sent from a Non-admin to All Admins
              // do some logic here i.e. if current user is an admin, open up one Chatbox
              // on the page for each unique `from_user_id`, and put data.message
              // in that box accordingly
        )
    
    class PrivateAdminMessagesChannel < ActionCable::Channel::Base
      def subscribed    
        stream_from :private_admin_messages_channel, coder: ActiveSupport::JSON do |data|
          from_user = User.find(data.fetch('from_user_id'))
          to_user = User.find(data['to_user_id']) if data['to_user_id']
          message = data.fetch('message')
    
          # authorize if "message" is sent to you (a non-admin), and also
          # authorize if "message" is sent to you (an admin)
    
          if (to_user && to_user == current_user) || (!to_user && current_user.is_admin?)
            # now, finally send the Hash data below and transmit it to the client to be received in the JS-side "received(data)" callback
            transmit(
              from_user_id: from_user.id,
              to_user_id: to_user&.id,
              message: message
            )
          end
        end
      end
    
      def send_message_to_admins(data)
        ActionCable.server.broadcast 'private_admin_messages_channel', 
          from_user_id: current_user.id,
          message: data.fetch('message')
      end
    
      def send_message_to_user_and_admins(data)
        from_user = current_user
    
        reject unless from_user.is_admin?
    
        ActionCable.server.broadcast 'private_admin_messages_channel', 
          from_user_id: from_user.id,
          to_user_id: data.fetch('to_user_id'),
          message: data.fetch('message')
      end
    end