Phoenix Channels - 从控制器广播 - 如何查找current_user?

时间:2016-07-17 11:17:21

标签: elixir phoenix-framework phoenix-channels

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

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

但是,我现在尝试做的是确保只有current_user才能访问为其表单广播的提交内容。 (例如,current_user将无法查看"表单的提交:2"如果表单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?!
    
  2. 之后,我可以看看是否user_id == submission.user_id,如果是真的则广播

    1. 如果无法做到这一点,那么最佳做法是什么,并确保只有current_user才能访问其表单提交?

1 个答案:

答案 0 :(得分:0)

使用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事件的任何地方广播,套接字通道将负责将事件推出有效负载中定义的三个用户。