2

websocket-railsを使用すると、コントローラーで次のコードを使用して、websocket パブリッシュ イベントをだますことができます。

WebsocketRails[:channel_name].trigger('event_name', { foo: "bar" }.to_json)

私の目標は、現在のユーザー専用の pub-sub チャネルを作成することです。たとえば、「新しいチャット メッセージが送信されました」というイベントを考えてみましょう。このイベントを受信者のチャネルのみにプッシュしたい。

現在、ID に基づいて各ユーザーに固有のチャンネル名を作成しています。次のコードをコントローラーに入れました (別の場所で current_user メソッドを定義しました:

WebsocketRails[:"user#{current_user.id}"].trigger("event_name", { foo: "bar" }.to_json)

次に、Javascript で、現在のユーザーを次のように自分のチャンネルにサブスクライブします。

<% if @current_user %>
  var dispatcher = new WebSocketRails('localhost:3000/websocket');
  channel = dispatcher.subscribe('user<%= @current_user.id %>'); 
  channel.bind('event_name', function(data) {
    console.log(data)
  });
<% end %>

その要点は、文字列補間を使用して、ユーザーごとに新しいチャネル、つまりチャネルを作成すること user12ですuser123

問題は、これが実際には安全でないことです。任意のユーザーは、Javascript を貼り付けるだけで、他のユーザーのプライベート チャネルにアクセスできます。たとえば、ユーザー #1 がユーザー #2 のニュース フィードにアクセスしたい場合、単にdispatcher.subscribe('user2').

この問題をどのように解決しますか? この機能が組み込まれている別の pub-sub ライブラリはありますか?

件名の WebsocketRails のwiki エントリを見て、次のコードを config/initializers/websockets.rb に追加してみました

WebsocketRails::EventMap.describe do
  namespace :websocket_rails do
    subscribe :subscribe_private, to: ConnectionsController, with_method: :authorize_channels
  end
end

app/controllers/connections_controller.rb に以下を追加

class ConnectionsController < WebsocketRails::BaseController
  def authorize_channels
    channel_name = WebsocketRails[message[:channel]]
    current_user = User.find_by(id: session["current_user_id"])
    if current_user && "user#{current_user.id}".eql?(channel_name)
      accept_channel current_user
    else
      deny_channel({ message: "auth failed" })
    end
  end
end

そして、他の場所で、私は電話していますWebsocketRails[:"user#{@current_user.id}"].make_private

しかし、これは何の効果もないようです。

4

0 に答える 0