【问题标题】:plug in phoenix controller插入凤凰控制器
【发布时间】:2016-10-24 04:20:19
【问题描述】:

我正在为 Phoenix 框架编写一个示例应用程序。 我的身份验证.ex:

defmodule Myapp.Plug.Authenticate do
  import Plug.Conn
  import Myapp.Router.Helpers
  import Phoenix.Controller

  def init(default), do: default

  def call(conn, default) do
    current_user = get_session(conn, :current_user)
    if current_user do
      assign(conn, :current_user, current_user)
    else
      conn
        |> put_flash(:error, 'You need to be signed in to view this page')
        |> redirect(to: session_path(conn, :new))
    end
  end
end

有一个控制器我不需要对单个操作进行身份验证:

defmodule Myapp.SharedLinkController do
  use Myapp.Web, :controller
  alias Myapp.SharedLink

  plug Myapp.Plug.Authenticate when action in [:new, :create]

...

end

它可以,但问题是有一个菜单显示取决于用户是否被授权:

<%= if Map.has_key?(@conn.assigns, :current_user) do %>
  <li>first</li>
<% else %>
  <li>second</li>
<% end %>

事实证明,在我不需要身份验证的页面操作上,我发现用户未获得授权,即使它已获得授权。我该如何解决这个问题?

【问题讨论】:

  • “我知道一个用户没有被授权”你的意思是你得到了 flash 和重定向,或者你得到了错误的菜单?
  • @Dogbert,我弄错了菜单
  • 注销时@conn.assigns[:current_user] 的值是多少?尝试添加&lt;%= inspect @conn.assigns[:current_user] %&gt; 并查看输出。
  • 这行得通吗:&lt;%= if assigns[:current_user] do %&gt;?
  • 您应该在重定向后调用函数中调用 halt/1 以防止调用下游的进一步插件。同样在您的模板中,您应该能够调用&lt;%= if @current_user do %&gt; 来检查用户是否经过身份验证。嗨

标签: elixir phoenix-framework


【解决方案1】:

我会将代码分成两步 - 首先尝试验证用户身份,从数据库加载并分配给连接 - 您始终可以运行此代码,然后简单地分配 nil,一个特殊的访客用户或什么都没有,无论你喜欢什么。第二个是根据连接中的分配强制对用户进行身份验证 - 这个只会在你需要的地方运行 - 就像你目前拥有的插件一样。

【讨论】:

  • 我明白吗,我必须做两个“身份验证” - 一个“软”选项,旨在分配当前用户或访客,第二个选项 - 一个“硬”,它如果用户未授权,则重定向到登录页面?
  • 是的,就是这样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-14
  • 1970-01-01
  • 1970-01-01
  • 2016-01-22
  • 2016-03-02
相关资源
最近更新 更多