凤凰卫视 - 从控制器广播 - 如何找到 current_user?

Phoenix Channels - broadcasting from controller - how to find current_user?

我有一个应用程序,我可以在其中广播一些 submission_controller 中的表单提交,如下所示:

Formerer.Endpoint.broadcast("forms:#{form.id}", "new_submission", payload)

但是,我现在要做的是确保只有 current_user 可以访问为其表单广播的提交。 (例如,如果表单 2 属于另一个用户,current_user 将无法查看 "forms:2" 的提交)。

我设法在频道 join 操作中做到这一点,方法是仅过滤我在连接操作中分配给频道的用户 ID 的表单:

user = Repo.get(Formerer.User, socket.assigns.user_id)

但是对于 broadcast 我没有 socket 可用。

我的问题:

  1. 有没有办法通过频道主题以某种方式找到套接字? 类似于:

    %Phoenix.Socket{assigns: %{user_id: user_id}, topic: "forms:1"} = ALL_OPEN_SOCKETS?!
    

之后我可以只查看是否 user_id == submission.user_id,如果为真则广播

  1. 如果那不可能,执行此操作并确保只有 current_user 可以访问他们的表单提交的最佳做法是什么?

使用 intercept api 并为事件创建一个 handle_out 函数。在 handle_out 函数中,您将拥有套接字。您可以验证存储在那里的 user_id。它是正确的,push socket, event, message,否则什么都不做,除了 {:ok, socket}

编辑

这是一个代码示例:

defmodule MyApp.Web.UserChannel do
  Use MyApp.Web, :channel

  intercept ["new_submission"]

  def handle_out("new_submission", msg, socket) do
    if msg[:user_id] == socket.assigns[:user_id] do
      push socket, "new_submission, msg
    end
    {:noreply, socket}
  end
end

然后您可以在任何地方广播 new_submission 事件,套接字通道将负责将事件推送到负载中定义的三个用户。