如何为经过身份验证的仅限用户的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
我测试了这个,它应该都能工作。你应该复习这本书。此外,您还可以查看我的身份验证包,了解更多信息