You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails中基于ActionCable实现Quote专属实时聊天室的隐私优化需求

Hey there! Let’s tackle that privacy issue with your Rails quote chatrooms—no more random users seeing conversations they shouldn’t. The core fix is to lock down your Action Cable subscriptions to individual Quote instances, so only the involved Client and Professionnel get messages for their specific conversation. Here’s how to do it step by step:

1. Update Client-Side Subscription to Target Specific Quotes

First, make sure your frontend sends the Quote ID when subscribing to the chat channel. This tells the server which conversation the user wants to join:

// app/javascript/channels/quote_chat_channel.js
import consumer from "./consumer"

// Replace <%= @quote.id %> with the actual quote ID from your view
consumer.subscriptions.create(
  { channel: "QuoteChatChannel", quote_id: <%= @quote.id %> },
  {
    connected() {
      // Optional: Add a success message or UI update here
    },

    received(data) {
      // Append the message to the correct chat container
      const chatContainer = document.getElementById(`quote-chat-${data.quote_id}`);
      if (chatContainer) chatContainer.innerHTML += data.message_html;
    }
  }
);

2. Secure the Server-Side Channel with Permission Checks

This is the critical part—your channel needs to verify that the connected user is actually part of the Quote before letting them subscribe. Update your channel class like this:

# app/channels/quote_chat_channel.rb
class QuoteChatChannel < ApplicationCable::Channel
  def subscribed
    @quote = Quote.find(params[:quote_id])
    
    # Check if the current user is either the quote's client or professional
    if authorized_user?
      # Stream messages ONLY to this specific quote's dedicated stream
      stream_for @quote
    else
      # Reject the subscription if the user has no business here
      reject
    end
  end

  def unsubscribed
    # Cleanup if needed (like marking the user as offline)
  end

  # Handle message sending with re-validated permissions
  def send_message(data)
    @quote = Quote.find(data['quote_id'])
    if authorized_user?
      # Create the message tied to the quote
      message = @quote.messages.create(
        content: data['content'],
        sender: current_client || current_professionnel
      )
      # Broadcast the message ONLY to the quote's stream
      QuoteChatChannel.broadcast_to(@quote, message_html: render_message(message))
    end
  end

  private

  # Helper to check if the current user is authorized for this quote
  def authorized_user?
    (current_client.present? && current_client == @quote.client) ||
    (current_professionnel.present? && current_professionnel == @quote.professionnel)
  end

  # Render the message partial to send to the frontend
  def render_message(message)
    ApplicationController.render(
      partial: 'messages/message',
      locals: { message: message }
    )
  end
end

3. Verify Your Connection Setup

Make sure your ApplicationCable::Connection class correctly identifies the current user (whether they’re a Client or Professionnel). For example:

# 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 current_client = Client.find_by(id: cookies.signed[:client_id])
        current_client
      elsif current_professionnel = Professionnel.find_by(id: cookies.signed[:professionnel_id])
        current_professionnel
      else
        reject_unauthorized_connection
      end
    end
  end
end

(Adjust this to match how you authenticate users in your app—devise tokens, session cookies, etc.)

Key Notes to Avoid Mistakes

  • Never skip permission checks: Even if the frontend only shows the chat to authorized users, always validate on the server—malicious users could manually subscribe to other quotes.
  • Use stream_for instead of global broadcasts: stream_for @quote creates a unique stream per quote, so messages only go to subscribers of that specific stream.
  • Reject unauthorized subscriptions: The reject method in subscribed will prevent users from joining streams they don’t have access to.

That should fix your privacy issue—now each Quote’s chat is only visible to the Client and Professionnel involved!

内容的提问来源于stack exchange,提问作者Maxence

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:52:59