Elixir 用户在开始登录后不会持久存在
我正在使用Guardian构建我的第一个Elixir应用程序,我遇到了一个问题,用户可以登录并通过身份验证,但在重定向到下一页时,Elixir 用户在开始登录后不会持久存在,elixir,phoenix-framework,guardian,Elixir,Phoenix Framework,Guardian,我正在使用Guardian构建我的第一个Elixir应用程序,我遇到了一个问题,用户可以登录并通过身份验证,但在重定向到下一页时,conn不再存储用户信息,并且Guardian.Plug.is_authenticated?返回false session\u controller.ex .... def create(conn, %{"session" => %{"email" => email, "password" => password}}) do case
conn
不再存储用户信息,并且Guardian.Plug.is_authenticated?
返回false
session\u controller.ex
....
def create(conn, %{"session" => %{"email" => email, "password" => password}}) do
case PhoenixApp.Auth.authenticate_user(email, password) do
{:ok, user} ->
conn
|> PhoenixApp.Auth.login(user)
|> put_flash(:info, "Welcome back!")
|> redirect(to: "/users")
{:error, _reason} ->
conn
|> put_flash(:error, "Invalid username or password.")
|> render("new.html")
end
end
...
...
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
end
scope "/", PhoenixAppWeb do
pipe_through [:browser]
get "/signup", UserController, :new
get "/login", SessionController, :new
post "/login", SessionController, :create
delete "/logout/:id", SessionController, :delete
end
scope "/", PhoenixAppWeb do
# Protected routes
pipe_through [:browser, :auth]
resources "/users", UserController, except: [:new]
get "/", PageController, :index
end
# Auth pipeline
pipeline :auth do
plug(PhoenixApp.Auth.AuthAccessPipeline)
end
...
...
def login(conn, user) do
conn
|> Guardian.Plug.sign_in(user)
|> assign(:current_user, user)
|> IO.inspect
|> put_user_token(user)
end
...
defmodule PhoenixApp.Auth.AuthAccessPipeline do
@moduledoc false
use Guardian.Plug.Pipeline,
otp_app: :phoenix_app,
error_handler: PhoenixApp.Auth.AuthErrorHandler
plug(Guardian.Plug.Pipeline,
module: PhoenixApp.Guardian,
error_handler: PhoenixApp.Auth.AuthErrorHandler
)
plug(Guardian.Plug.VerifySession, claims: %{"typ" => "access"})
# plug(Guardian.Plug.EnsureAuthenticated)
# plug(Guardian.Plug.LoadResource)
end
router.ex
....
def create(conn, %{"session" => %{"email" => email, "password" => password}}) do
case PhoenixApp.Auth.authenticate_user(email, password) do
{:ok, user} ->
conn
|> PhoenixApp.Auth.login(user)
|> put_flash(:info, "Welcome back!")
|> redirect(to: "/users")
{:error, _reason} ->
conn
|> put_flash(:error, "Invalid username or password.")
|> render("new.html")
end
end
...
...
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
end
scope "/", PhoenixAppWeb do
pipe_through [:browser]
get "/signup", UserController, :new
get "/login", SessionController, :new
post "/login", SessionController, :create
delete "/logout/:id", SessionController, :delete
end
scope "/", PhoenixAppWeb do
# Protected routes
pipe_through [:browser, :auth]
resources "/users", UserController, except: [:new]
get "/", PageController, :index
end
# Auth pipeline
pipeline :auth do
plug(PhoenixApp.Auth.AuthAccessPipeline)
end
...
...
def login(conn, user) do
conn
|> Guardian.Plug.sign_in(user)
|> assign(:current_user, user)
|> IO.inspect
|> put_user_token(user)
end
...
defmodule PhoenixApp.Auth.AuthAccessPipeline do
@moduledoc false
use Guardian.Plug.Pipeline,
otp_app: :phoenix_app,
error_handler: PhoenixApp.Auth.AuthErrorHandler
plug(Guardian.Plug.Pipeline,
module: PhoenixApp.Guardian,
error_handler: PhoenixApp.Auth.AuthErrorHandler
)
plug(Guardian.Plug.VerifySession, claims: %{"typ" => "access"})
# plug(Guardian.Plug.EnsureAuthenticated)
# plug(Guardian.Plug.LoadResource)
end
auth.ex
....
def create(conn, %{"session" => %{"email" => email, "password" => password}}) do
case PhoenixApp.Auth.authenticate_user(email, password) do
{:ok, user} ->
conn
|> PhoenixApp.Auth.login(user)
|> put_flash(:info, "Welcome back!")
|> redirect(to: "/users")
{:error, _reason} ->
conn
|> put_flash(:error, "Invalid username or password.")
|> render("new.html")
end
end
...
...
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
end
scope "/", PhoenixAppWeb do
pipe_through [:browser]
get "/signup", UserController, :new
get "/login", SessionController, :new
post "/login", SessionController, :create
delete "/logout/:id", SessionController, :delete
end
scope "/", PhoenixAppWeb do
# Protected routes
pipe_through [:browser, :auth]
resources "/users", UserController, except: [:new]
get "/", PageController, :index
end
# Auth pipeline
pipeline :auth do
plug(PhoenixApp.Auth.AuthAccessPipeline)
end
...
...
def login(conn, user) do
conn
|> Guardian.Plug.sign_in(user)
|> assign(:current_user, user)
|> IO.inspect
|> put_user_token(user)
end
...
defmodule PhoenixApp.Auth.AuthAccessPipeline do
@moduledoc false
use Guardian.Plug.Pipeline,
otp_app: :phoenix_app,
error_handler: PhoenixApp.Auth.AuthErrorHandler
plug(Guardian.Plug.Pipeline,
module: PhoenixApp.Guardian,
error_handler: PhoenixApp.Auth.AuthErrorHandler
)
plug(Guardian.Plug.VerifySession, claims: %{"typ" => "access"})
# plug(Guardian.Plug.EnsureAuthenticated)
# plug(Guardian.Plug.LoadResource)
end
auth\u access\u pipeline.ex
....
def create(conn, %{"session" => %{"email" => email, "password" => password}}) do
case PhoenixApp.Auth.authenticate_user(email, password) do
{:ok, user} ->
conn
|> PhoenixApp.Auth.login(user)
|> put_flash(:info, "Welcome back!")
|> redirect(to: "/users")
{:error, _reason} ->
conn
|> put_flash(:error, "Invalid username or password.")
|> render("new.html")
end
end
...
...
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
end
scope "/", PhoenixAppWeb do
pipe_through [:browser]
get "/signup", UserController, :new
get "/login", SessionController, :new
post "/login", SessionController, :create
delete "/logout/:id", SessionController, :delete
end
scope "/", PhoenixAppWeb do
# Protected routes
pipe_through [:browser, :auth]
resources "/users", UserController, except: [:new]
get "/", PageController, :index
end
# Auth pipeline
pipeline :auth do
plug(PhoenixApp.Auth.AuthAccessPipeline)
end
...
...
def login(conn, user) do
conn
|> Guardian.Plug.sign_in(user)
|> assign(:current_user, user)
|> IO.inspect
|> put_user_token(user)
end
...
defmodule PhoenixApp.Auth.AuthAccessPipeline do
@moduledoc false
use Guardian.Plug.Pipeline,
otp_app: :phoenix_app,
error_handler: PhoenixApp.Auth.AuthErrorHandler
plug(Guardian.Plug.Pipeline,
module: PhoenixApp.Guardian,
error_handler: PhoenixApp.Auth.AuthErrorHandler
)
plug(Guardian.Plug.VerifySession, claims: %{"typ" => "access"})
# plug(Guardian.Plug.EnsureAuthenticated)
# plug(Guardian.Plug.LoadResource)
end
my
login的IO.inspect(conn)
方法为刚刚在中登录的用户返回一个JSONified User结构,该用户在当前用户下分配键,并且还存储一个带有令牌的用户令牌。如果在重定向到/users
后检查连接
,则分配中的当前\u用户
为nil
,并且没有用户\u令牌
HTTP协议是无状态的。这意味着redirect\u to
不返回任何内容,然后向浏览器返回如何加载另一(下一)页的指令
调用重定向
后,auth请求中的conn与所有存储的用户资源和令牌一起消失
现在,浏览器启动到服务器的新连接,这将创建绝对新的连接,而该连接对以前的连接一无所知(例如,如果一台服务器有群集,则可以由另一台服务器处理)
那么,如何在连接之间“存储状态”(在本例中为用户资源)
当然有饼干。应该在一个请求中将用户令牌放在cookie中,并在接下来的所有请求中从cookie中检索令牌
公平地说,Guardian有两种不同的方法在cookie中存储和检索令牌:直接使用或使用会话:/
put\u session\u token
会在sign\u in
中自动调用,因此管道中应该包含用于会话的插头。我编辑了我的原始帖子以显示我的身份验证管道,并更新了我的router.ex
以显示哪些路由现在受到保护,哪些路由没有受到保护。我已尝试在管道中包含用于验证会话的插件,但是如果我这样做,我将在登录并重定向到用户索引后立即收到无效令牌
消息。我仍然没有在路由器文件中看到管道。问题可能是因为您从浏览器管道中删除了会话插件。受保护的路由正在通过authline进行管道传输:管道通过[:browser,:auth]
,您的意思是需要其他内容吗?我误解了您的评论,我已扩展了代码以显示:browser
管道。在生成新的phoenix应用程序后,它不会从默认值进行修改,并且未删除:fetch\u session
插件。您正在使用Guardian.plug.sign\u in(user)
。但是文档告诉我们使用MyApp.Guardian.Plug.sign\u in(用户)
您的代码中有这个模块吗?