代码之家  ›  专栏  ›  技术社区  ›  Sorebrez

基于用户角色呈现模板的各个部分

  •  0
  • Sorebrez  · 技术社区  · 6 年前

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

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

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

    1. 使用“/管理”路由并限制对其的访问。这似乎是最常用的方式,但我不想这样做,因为在我的情况下,管理员只是一个有特权的普通用户,基本上不需要为管理员提供完整的路由。我必须创建新的控制器、新的模板等等。
    2. 所以我的下一个想法是:“只需呈现另一个模板,并从用户模板中删除这些按钮”。嗯,它可以工作,但基本上与1)相同。我将不得不复制所有索引的内容。html和其他一些模板。此外,如果我想添加另一个角色,可能是“经理”或其他角色,我必须再次复制它。随着时间的推移,这似乎无法维护。
    3. 向模板本身添加一些逻辑,如<%=如果是\ U admin?do%>html内容<%结束%>。我知道这不会有什么坏处,因为我用控制器中的插件仔细检查了权限,但无论如何。。。这看起来也很“脏”,因为我不想在模板中使用这种逻辑。

    有没有人有其他想法,或者有没有提到讨论过这个问题的人?我只能找到关于1)和如何实现它的文章。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Dogbert    6 年前

    我喜欢将权限逻辑保留在一个地方,并在控制器和模板中使用它。灵感源自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 %>