Укажите маршруты ресурсов, для которых требуется аутентифицированный пользователь в Elixir Phoenix - PullRequest
0 голосов
/ 13 июля 2020

Я использую phx_gen_auth для входа пользователя, регистрации и аутентификации в моем приложении Elixir Phoenix. Он поставляется с разъемом :require_authenticated_user, чтобы решить, требует ли конкретный маршрут c аутентификация пользователя перед доступом.

Если у меня есть ресурс сообщений в моем router.ex, который дает мне все стандартные действия:

resources "/posts", PostController

Как мне лучше всего организовать определенные маршруты, чтобы пользователь должен был войти в систему? Например, просмотр всех сообщений или просмотр одного сообщения не требует входа в систему. Но создание, редактирование, обновление, удаление сообщения должны потребовать от пользователя входа в систему.

Есть ли способ управлять тем, какие маршруты требуют авторизации, без указания всех моих маршрутов отдельно в двух отдельных блоках scope, которые есть отдельные pipe_through с?

Ответы [ 2 ]

1 голос
/ 13 июля 2020

Единственный известный мне способ сделать это - использовать 2 прицела. Вот пример, в котором я дважды объявляю одну и ту же область видимости, но в одной из них используется дополнительный конвейер :auth. Обратите внимание, как я использую параметр :only, чтобы указать, какие методы контроллера разрешены:

  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug :put_secure_browser_headers
  end

  pipeline :auth do
    plug MyAppWeb.Auth
  end

  scope "/", MyAppWeb do
    pipe_through :browser

    resources "/posts", PostController, only: [:index]
  end

  scope "/", MyAppWeb do
    pipe_through :browser
    pipe_through :auth

    resources "/posts", PostController, only: [:show, :new, :create]
  end

Хитрость заключается в том, чтобы использовать :only, чтобы сказать, какие из функций вашего контроллера разрешено вызывать в этом путь. Маршрутизатор будет соответствовать первому найденному, поэтому, если вы дважды используете один и тот же метод в обеих областях, скажем :index, тогда он будет использовать первую область видимости (то есть первую лексически определенную область видимости. файл).

Надеюсь, в этом есть смысл. Я могу объяснить больше, если хотите.

PS Может, поэкспериментируйте и посмотрите, работает ли:

  scope "/", MyAppWeb do
    pipe_through :browser
    resources "/posts", PostController, only: [:index]

    pipe_through :auth
    resources "/posts", PostController, only: [:show, :new, :create]
  end
0 голосов
/ 13 июля 2020

Как указано в документации для Phoenix.Router.pipeline/2

Каждый раз, когда вызывается pipe_through/1, новые конвейеры добавляются к ранее указанным.

Тем не менее, это будет работать:

scope "/", MyWeb do
  pipe_through [:browser]
  get "/index", PostController

  pipe_through, :auth
  get "/show", PostController
  post "/create", PostController
  put "/update", PostController
end

Другое решение - использовать штекер прямо в контроллере

defmodule MyWeb.PostController do
  plug :auth when action in ~w|show create update|a

  def show(conn, params) do
    # ...
  end
end
...