riverrun / phauxth

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

Working on Phoenix Liveview #115

Open 9to1url opened 4 years ago

9to1url commented 4 years ago

Problem

Tried to use on Liveview websocket, but not working

Solution

Need to work on Liveview

Additional info

Looks like not able to compile: defmodule HelloWeb.UserLive.Index do use Phoenix.LiveView

lib/hello_web/live/user_live/index.ex:11: undefined function plug/1

riverrun commented 4 years ago

First of all, sorry about the delay in getting back to you - I haven't felt well recently.

About the undefined function plug/1 error, if you import Plug.Conn, that should solve that problem. However, I am not sure how liveview works, and so I don't know how often, or if, the plug function will be run.

karolsluszniak commented 4 years ago

Just FYI, I had no problem making Phauxth work with LiveView using the following "helper" module:

defmodule PlaygroundWeb.Auth.Live do
  @moduledoc """
  Provides authenticated user to live views.

  ## Usage

      defmodule PlaygroundWeb.HomeLive do
        use PlaygroundWeb, :live
        import PlaygroundWeb.Auth.Live

        def mount(_params, session, socket) do
          socket = put_current_user(socket, session)

          # ...
        end

  """

  def get_current_user(session) do
    with {:ok, session_id} <- Map.fetch(session, "phauxth_session_id"),
         user = %{} <- Playground.Accounts.get_by(%{"session_id" => session_id}) do
      user
    else
      _ -> nil
    end
  end

  def put_current_user(socket, session) do
    Phoenix.LiveView.assign(socket, current_user: get_current_user(session))
  end
end

My concern here in context of long-lived live view sessions is that this solution is affected by session expiration after the @max_age from Session passes. This is not live view's flaw per se as regular HTTP routes do the same - it simply seems there's no "session renewal" mechanism built into Phauxth.Authenticate.

@riverrun From your perspective, how this should be approached both in context of regular HTTP requests and long-lived live views? I saw https://github.com/riverrun/phauxth/issues/38 for API tokens so I'm wondering if the solution would be similar for sessions e.g. to add HTTP plug after Phauxth.Authenticate that renews the session when it's about to expire - not too often of course e.g. when we've 1 hour left in the session. In such case, if we'd bump expires_at in existing Session record instead of deleting & inserting it, live view would always have an up-to-date phauxth_session_id. Is there a downside or security hole in here?

9to1url commented 4 years ago

I think more and more clear is many apps moving to LiveView direction, LiveView support is mandatory now. Please implement. Also Phx 1.5 out. thanks!!!

dsignr commented 3 years ago

Just FYI, I had no problem making Phauxth work with LiveView using the following "helper" module:

defmodule PlaygroundWeb.Auth.Live do
  @moduledoc """
  Provides authenticated user to live views.

  ## Usage

      defmodule PlaygroundWeb.HomeLive do
        use PlaygroundWeb, :live
        import PlaygroundWeb.Auth.Live

        def mount(_params, session, socket) do
          socket = put_current_user(socket, session)

          # ...
        end

  """

  def get_current_user(session) do
    with {:ok, session_id} <- Map.fetch(session, "phauxth_session_id"),
         user = %{} <- Playground.Accounts.get_by(%{"session_id" => session_id}) do
      user
    else
      _ -> nil
    end
  end

  def put_current_user(socket, session) do
    Phoenix.LiveView.assign(socket, current_user: get_current_user(session))
  end
end

My concern here in context of long-lived live view sessions is that this solution is affected by session expiration after the @max_age from Session passes. This is not live view's flaw per se as regular HTTP routes do the same - it simply seems there's no "session renewal" mechanism built into Phauxth.Authenticate.

@riverrun From your perspective, how this should be approached both in context of regular HTTP requests and long-lived live views? I saw #38 for API tokens so I'm wondering if the solution would be similar for sessions e.g. to add HTTP plug after Phauxth.Authenticate that renews the session when it's about to expire - not too often of course e.g. when we've 1 hour left in the session. In such case, if we'd bump expires_at in existing Session record instead of deleting & inserting it, live view would always have an up-to-date phauxth_session_id. Is there a downside or security hole in here?

A simpler solution that I would just try is redirect the user to the login page post expiry notice from the authenticate function. If your application requires long lived sessions, then the right way is probably to increase the expiry of the session itself. That's how I would do it anyway, just my $0.02. Hence, I think if we just use your helper and have authenticate redirect to login post expiry would close this issue IMO.