2014-09-26 4 views
8

У меня есть небольшое приложение Phoenix, позволяющее пользователям входить в систему и проконсультироваться с их профилем. Я использовал следующий простой маршрут:Как ограничить доступ к определенным маршрутам в Фениксе?

resources "/users", MyApp.UserController 

Но это позволяет каждому пользователю видеть список пользователей через :index действия, а также удалять или обновлять любой пользователь.

Что является самым простым способом ограничить доступ только к администраторам? Должен ли я добавить чек перед каждым действием? Или я должен создать ресурс "/admin", который будет обрабатывать эти операции? Каков рекомендуемый способ?

ответ

11

Вы должны использовать вилку в 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, как вы сделали ссылку на ограниченную функциональность.

+0

Ницца! Он работает нормально. Я как-то понял, что есть что-то делать со штекером, учитывая то, что я читал в примере Phoenix.Controller api doc, но я не был уверен, что он должен был применяться конечными пользователями, или если это было для ядра Разработчики. Кстати, есть способ извлечь домен источника подключения из conn? Я хочу перенаправить на вызывающий url (с разными аргументами) в случае успеха sso login ... – adanselm

1

Можно также определить отдельный трубопровод для прошедших проверку подлинности конечных точек:

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 

админ сфера является лишь примером, это может быть все что угодно, но идея трубопровода остается неизменной.

Этот метод будет держать ваши контроллеры более чистыми, но не всегда возможен. Это зависит от ваших конкретных требований.

Смежные вопросы