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
しかし、これは何の効果もないようです。