用户在开始登录后无法坚持

时间:2019-06-29 17:40:50

标签: elixir phoenix-framework phoenix guardian

我正在使用Guardian构建我的第一个Elixir应用程序,但遇到一个问题,用户可以登录并通过身份验证,但是在重定向到下一页时,conn不再存储用户信息,而{{ 1}}返回false。

Guardian.Plug.is_authenticated?

session_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 ...

router.ex

... 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 ...

auth.ex

... def login(conn, user) do conn |> Guardian.Plug.sign_in(user) |> assign(:current_user, user) |> IO.inspect |> put_user_token(user) end ...

auth_access_pipeline.ex

我的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 方法中的IO.inspect(conn)为刚刚在login下的assigns键中登录的用户返回JSONified User结构,并存储一个{{ 1}}和令牌。如果您在重定向到current_user后检查user_token,则分配中的conn/users,并且没有current_user

1 个答案:

答案 0 :(得分:0)

HTTP协议是无状态的。这意味着redirect_to只会返回浏览器如何加载另一个(下一个)页面的指令

调用redirect之后,auth请求中的

conn 消失,所有存储的用户资源和令牌都消失了。

现在,浏览器启动与服务器的新连接,这将创建一个绝对全新的 con ,该服务器对以前的服务器一无所知(例如,如果有一个集群)。

那么,如何在连接之间 之间“存储状态”(在我们的情况下为用户资源)?

当然带有 cookies 。应该在一个请求中将用户令牌放入cookie中,然后在所有下一个请求中从cookie中检索令牌。

公平地说,监护人有两种不同的方式在cookie中存储和检索令牌:直接通过remember_me / VerifyCookie Plug或会话:put_session_token / VerifySession Plug

put_session_tokensign_in内部被自动调用,因此您的管道应包括用于会话的插件。