【问题标题】:render parts of template based on user role根据用户角色渲染部分模板
【发布时间】:2018-05-04 16:02:47
【问题描述】:

我的问题是关于仅显示用户被授权的模板的那些部分。 让我们假设有一个只有用户和用户角色的项目,以及由 phx.gen.html 生成的模板和控制器。设置路由“/users”,我们会得到一个漂亮的表格,其中包含所有用户数据和“显示”、“编辑”和“删除”按钮。

用户角色可能只是普通的“用户”和“管理员”。现在我希望管理员能够删除和编辑所有用户,但“用户”应该只能编辑他自己以及我的问题是什么,他应该只能看到这些按钮以供输入。

我已经为相应的操作设置了一些插件,因此普通“用户”无法编辑、删除甚至显示其他用户,但他甚至不应该知道这样做的选项。所以,我想隐藏这些按钮。以下是我遇到或想到的解决方案,但它们似乎都不是真正适用的。

  1. 使用“/admin”路由并限制对其的访问。这似乎是最常用的方式,但我不想这样做,因为在我的情况下,管理员只是特权普通用户,基本上不需要管理员的完整路线。我必须创建新的控制器、新的模板等等。
  2. 所以我的下一个想法是:“只需渲染另一个模板并从用户模板中删除这些按钮”。好吧,它可以工作,但它与 1) 基本相同。我将不得不为所有 index.html 和其他一些模板复制内容。此外,如果我想添加另一个角色,可能是“经理”或其他角色,我必须再次复制它。随着时间的推移,这似乎是不可维护的。
  3. 向模板本身添加一些逻辑,例如 html-things 。我知道此时它不会受到伤害,因为我使用控制器中的插件仔细检查了权限,但无论如何......这似乎也很“脏”,因为我不希望模板中出现这种逻辑。

任何人有其他想法或可能是对讨论此问题的人的参考?我只能找到关于 1) 以及如何实现它的文章。

【问题讨论】:

    标签: elixir phoenix-framework


    【解决方案1】:

    我喜欢将权限逻辑保存在一个地方,并在控制器和模板中使用它。受 Ruby on Rails 旧的 cancan gem 的启发,我定义了一个函数:

    defmodule MyApp.Can do
      def can?(_user, :create, Post), do: true
      def can?(user, :delete, %Post{} = post), do: user.is_admin || post.user_id == user.id
      ...
    end
    

    现在在控制器中,使用这个函数进行授权:

    def delete(...) do
      ...
      if MyApp.Can.can?(current_user, :delete, post) do
        ...
      else
        ...
      end
    end
    

    在模板中:

    <%= MyApp.Can.can?(@current_user, :delete, @post) %> <Delete Button> <% end %>
    

    【讨论】:

    • 谢谢多伯特。这不完全是我所寻找的,但它是我第 3 点的一个很好的实现,具有集中逻辑。深入研究后,我发现 Policy_Wonk github.com/boydm/policy_wonk。我想我会用这个。所以,再次感谢你带领我朝着正确的方向前进 ;-)
    • 只是另一个补充:Policy_wonk 对我来说有点过分了。现在对我有用的是使用您的解决方案@Dogbert,而不是调用 MyApp.Can.can?在控制器动作中,我在我的 Plugs 中调用它。这样,控制器逻辑保持干净,授权由插件处理,如果有人试图做他未经授权的事情,管道将在调用任何控制器操作之前停止。
    猜你喜欢
    • 2011-06-12
    • 2018-04-21
    • 2011-05-23
    • 1970-01-01
    • 2013-01-22
    • 1970-01-01
    • 2017-10-19
    • 1970-01-01
    • 2022-01-24
    相关资源
    最近更新 更多