Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何为经过身份验证的仅限用户的Elixir Phoenix保护路由_Elixir_Phoenix Framework - Fatal编程技术网

如何为经过身份验证的仅限用户的Elixir Phoenix保护路由

如何为经过身份验证的仅限用户的Elixir Phoenix保护路由,elixir,phoenix-framework,Elixir,Phoenix Framework,我在我的应用程序中创建了几个路由 scope "/", Socialistical do pipe_through :browser # Use the default browser stack get "/", UserController, :index get "/sign_up", UserController, :sign_up post "/create_user", UserController, :create options "

我在我的应用程序中创建了几个路由

  scope "/", Socialistical do
    pipe_through :browser # Use the default browser stack


    get "/", UserController, :index
    get "/sign_up", UserController, :sign_up
    post "/create_user", UserController, :create
    options "/create_user", UserController, :nothing

    post "/session", SessionController, :create
    delete "/logout", SessionController, :delete

    get "/dashboard", DashboardController, :index
  end
除仪表板外,其他路线也可供公众使用。但我只想为经过身份验证的用户保护仪表板路由。我已经创建了一个会话模型

defmodule Socialistical.Session do
  alias Socialistical.User

  def current_user(conn) do
    id = Plug.Conn.get_session(conn, :current_user)
    if id, do: Socialistical.Repo.get(User, id)
  end

  def logged_in?(conn), do: !!current_user(conn)
end

我想利用这两种方法来保护所有即将到来的路线,这些路线将只提供给真正的用户,请在这方面帮助我。我有点不知道如何将其制作/转换为插件

下面是一个简单的例子。本示例仅处理验证登录用户的操作。它不处理重定向到登录页面的操作

这是插头

defmodule Socialistical.Session do
  @behaviour Plug
  import Plug.Conn
  alias Socialistical.Accounts.User
  alias Socialistical.Repo

  def current_user(conn), do: conn.assigns[:current_user]
  def logged_in?(conn), do: !!current_user(conn)

  def init(opts \\ []) do
    # simple example to show how options can be passed
    %{error: opts[:error] || "Not authorized"}
  end

  def call(conn, opts \\ []) do
    if user = get_user(conn) do
      # we have a session so store it for latter access
      assign conn, :current_user, user
    else
      # not session
      halt_with_error conn, opts[:error]
    end
  end

  defp halt_with_error(conn, error) do
    conn
    |> send_resp(401, error)
    |> halt
  end

  defp get_user(conn) do
    case Plug.Conn.get_session(conn, "current_user") do
      nil -> nil
      id -> Repo.get(User, id)
    end
  end
end
和路由器:

defmodule Socialistical.Web.Router do
  use Socialistical.Web, :router
  # ...
  pipeline :protected do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug :put_secure_browser_headers
    plug Socialistical.Session
  end

  scope "/", Socialistical.Web do
    pipe_through :browser # Use the default browser stack

    get "/", PageController, :index
    get "/login/:id", PageController, :login

    # just here for the example
    resources "/users", UserController
  end

  scope "/", Socialistical.Web do
    pipe_through :protected
    get "/protected", PageController, :protected
  end
end
这是一个用于测试的控制器。我添加了一个登录操作,只是为了测试它是否有效。它仅用于演示目的,因为它不验证用户,只创建会话

defmodule Socialistical.Web.PageController do
  use Socialistical.Web, :controller
  alias Socialistical.Accounts

  def index(conn, _params) do
    render conn, "index.html"
  end

  def protected(conn, _params) do
    render conn, "protected.html"
  end

  def login(conn, %{"id" => id}) do
    user = Accounts.get_user!(id)
    conn
    |> put_session("current_user", user.id)
    |> assign(:current_user, user)
    |> redirect(to: "/")
  end
end
我测试了这个,它应该都能工作。你应该复习这本书。此外,您还可以查看我的身份验证包,了解更多信息