如何限制凤凰​​城某些路线的访问?

时间:2014-09-26 08:44:16

标签: elixir phoenix-framework

我有一个小凤凰应用程序,允许用户登录并查阅他们的个人资料。我使用了以下简单的路线:

resources "/users", MyApp.UserController

但这允许每个用户通过:index操作查看用户列表,以及删除或更新任何用户。

仅限制管理员访问权限的最简单方法是什么?我应该在每个动作前加一张支票吗?或者我应该创建一个"/admin"资源来处理这些操作?推荐的方式是什么?

2 个答案:

答案 0 :(得分:12)

您可以使用UserController中的插件。 0.4.x无法有条件地插入,但你可以通过以下方式实现你想要的东西:

defmodule MyApp.UserController do
  use Phoenix.Controller

  plug :authenticate, :admin
  plug :action

  def index(conn, _) do
    render conn, "index"
  end

  def create(conn, params) do
    # do the creating
  end
  ...

  defp authenticate(conn, :admin) do
    do_auth(conn, action_name(conn))
  end
  defp do_auth(conn, action) when action in [:create, :update, :destroy] do
    if AdminAuth.authenticated?(conn) do
      conn
    else
      halt conn
    end
  end
  defp do_auth(conn, _action), do: conn
end

0.5即将发生的变化将允许更容易的条件插件,即:

defmodule MyApp.UserController do
  use Phoenix.Controller

  plug :authenticate, :admin when action in [:create, :update, :destroy]

  def index(conn, _) do
    render conn, "index"
  end

  def create(conn, params) do
    # do the creating
  end
  ...

  defp authenticate(conn, :admin) do
    if AdminAuth.authenticated?(conn) do
      conn
    else
      halt conn
    end
  end
end

最好将控制器与公共/限制访问分开,因此我会添加一个Admin.UserController,就像您对受限功能的引用一样。

答案 1 :(得分:2)

您还可以为经过身份验证的端点定义单独的管道:

defmodule MyApp.Router do
  use MyApp.Web, :router

  pipeline :admin do 
    plug :accepts, ["html"]

    plug Authentication # this represents some plug that provides authentication
  end

  scope "/", MyApp do
    pipe_through :browser

    resources "/things", ThingController
  end

  scope "/admin", MyApp do
    pipe_through :admin

    resources "/admin/things", Admin.ThingsController
  end
end

管理范围只是一个例子,它可以是你喜欢的任何东西,但管道思想保持一致。

此技术可使您的控制器更清洁,但并非总是可行。这取决于您的确切要求。