Redirect from plug and redirect from LiveView


I’d like to redirect unauthenticated users to my login page.

According to these considerations, I added a redirect plug in my router which works as intended:

defmodule CloudNewsWeb.Plugs.CheckLoggedIn do
  import Plug.Conn

  use Phoenix.Controller

  def init(default), do: default

  def call(%{assigns: %{current_user: user}} = conn, _default) do
    case user do
      nil ->
        |> redirect(to: "/login?from=#{URI.encode_www_form(conn.request_path)}")
        |> halt()

      _ ->


In my liveview I added:

def mount(_params, session, socket) do
    user = get_current_user(session)

    if user do
       {:ok, socket}
    else do
      {:ok, redirect(socket, to: Routes.login_path(socket, :show))}

As a result of this I get two redirects, one from the plug and one from the LiveView, I don’t understand why I would need that.

[info] Sent 302 in 3ms
[info] Sent 302 in 3ms

And I get an error from Cowboy:

[error] Ranch listener CloudNewsWeb.Endpoint.HTTP had connection process started with :cowboy_clear:start_link/4 at #PID<0.1162.0> exit with reason: {:function_clause, [{:cowboy_http, :commands, ...

Do you have any idea on how to fix this?

Thank you !

1 Like

Documentation example doesn’t use a plug but helpers and do the checks on mounts.
I am not sure plugs work ok for reconnect attempts etc.

The notes say this

One possible concern in this approach is that in regular HTTP requests the current user will be fetched twice: once in the HTTP request and again on mount/3. You can address this by using the assign_new/3 function, that will reuse any of the connection assigns from the HTTP request:

1 Like

Ranch listener error is coming from this. I have had a similar one when I was trying to halt the request lifecycle while it was in play - or another one coming in.

1 Like

Thanks for your answer :slight_smile:

I understand better now, I thought I could use both a redirect plug and a redirect in my LiveView.

If I remove the plug, it works fine but I lose the ability to scope my routes and I have to handle auth in all liveviews like in the article above.

I’ll go with that!

You can always move the logic to helper and call from your live views as the documentation demonstrated.

1 Like

Yes that’s what I did :slight_smile: