riverrun / phauxth

Not actively maintained - Authentication library for Phoenix, and other Plug-based, web applications
409 stars 20 forks source link

Question: Can you set the request_path via a string query? #91

Closed joshchernoff closed 5 years ago

joshchernoff commented 5 years ago

I want to create a sign in link via. <%= link "Login", to: Routes.session_path(@conn, :new, request_path: "/foobar" ) %>

After further inspection it looks as if passing a string query is not enough to provide the login a way to redirect the user to a desired path.

in the case of the link above the request_path param is simply ignored after login. Maybe its not the request path I should be trying to set?

I want to be able to pass the follow up request_path upon successful sign in. I understand this will work if I try to call an action that requires login but in my use case that path is not something I can initially call.

In my case I'm creating a comment section for a post and I wanted to add a link that simply said to log in if you want to submit a comment. I'd like to redirect them back to the same blog post where the comment section is upon signing in. I was thinking maybe if I can pass the param request_path as a string query but I'm not seeing anywhere in the code that would use it.

riverrun commented 5 years ago

First, a note about the request_path*. In the authorize.ex file in the example app, we are adding it to the Plug session (in the need_login function), and then in the session_controller, we are using that value to redirect the user upon successful login.

In your case, if you can find a way of adding the request_path to the Plug session, then you can use the same mechanism to redirect the user when they log in. You could, for example, add it to the session for any call by a guest user to a blog post, and then it will be constantly overwritten until the user logs in - then the user will be redirected to the most recent value of request_path.

Let me know if you have any further comments / questions.

joshchernoff commented 5 years ago

Oh man I feel dumb, I assumed that logic was in phauxth

joshchernoff commented 5 years ago

Ok I think I get it, so if for example if I wanted to allow a string query like I have above I would assign that value to a hidden form field on the sessions new form and then pass it in to the create and update the redirect(to: get_session(conn, :request_path) || Routes.user_path(conn, :index)) to account for the possibility of the request_path via the params vs the session.

joshchernoff commented 5 years ago

For anyone who happens across this, this is what I did to make it work the way I wanted with the string query

for my session controller.

def new(conn, %{"request_path" => request_path}) do
    render(conn, "new.html", request_path: request_path)
  end

  def new(conn, _) do
    render(conn, "new.html", request_path: nil)
  end

  def create(conn, %{"session" => %{"request_path" => request_path}} = params) do
    {_, params} = pop_in(params, ["session", "request_path"])

    conn
    |> put_session(:request_path, request_path)
    |> create(params)
  end

  def create(conn, %{"session" => params}) do
    case Login.verify(params) do
      {:ok, user} ->
        {:ok, %{id: session_id}} = Sessions.create_session(%{user_id: user.id})

        conn
        |> delete_session(:request_path)
        |> Authenticate.add_session(session_id)
        |> add_remember_me(user.id, params)
        |> put_flash(:info, "User successfully logged in.")
        |> redirect(to: get_session(conn, :request_path) || Routes.user_path(conn, :index))

      {:error, message} ->
        conn
        |> put_flash(:error, message)
        |> redirect(to: Routes.session_path(conn, :new))
    end
  end

And in my new session view.

<%= if @request_path do %>
  <%= hidden_input f, :request_path, value: @request_path%>
<% end %>

Then that way if I want to explicitly redirect a user to a given known path upon login I make a button like so.

<%= link "Login", to: Routes.session_path(@conn, :new, request_path: "/foobar" ) %>