我有一个小凤凰应用程序,允许用户登录并查阅他们的个人资料。我使用了以下简单的路线:
resources "/users", MyApp.UserController
但这允许每个用户通过:index
操作查看用户列表,以及删除或更新任何用户。
仅限制管理员访问权限的最简单方法是什么?我应该在每个动作前加一张支票吗?或者我应该创建一个"/admin"
资源来处理这些操作?推荐的方式是什么?
答案 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
管理范围只是一个例子,它可以是你喜欢的任何东西,但管道思想保持一致。
此技术可使您的控制器更清洁,但并非总是可行。这取决于您的确切要求。