【问题标题】:Phoenix Channels - broadcasting from controller - how to find current_user?Phoenix Channels - 从控制器广播 - 如何找到 current_user?
【发布时间】:2016-11-20 02:40:11
【问题描述】:

我有一个应用程序,我在 submit_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 才能访问他们提交的表单?

【问题讨论】:

  • 既然您已经使用了Endpoint.broadcast/3,为什么您不验证来自客户端的提交。就像您可以在您的submission_controller 中提交您的user_id 和您的payload,然后您验证它当将payload 广播到form_channel 时正在监听new_submission 事件。
  • 表示提交信息仍会被广播。如果不是正确的用户,我的困境是如何阻止它们被广播。

标签: elixir phoenix-framework phoenix-channels


【解决方案1】:

使用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 事件,并且套接字将通道将负责将事件推送到有效负载中定义的三个用户。

【讨论】:

    猜你喜欢
    • 2016-03-01
    • 1970-01-01
    • 2018-12-24
    • 1970-01-01
    • 2013-09-30
    • 2021-07-09
    • 1970-01-01
    • 2012-09-11
    • 1970-01-01
    相关资源
    最近更新 更多