Intercepting invalid cookies/sessions?

Hi folks,

I have a phoenix app powering an API. Currently, authentication is done via session storage & cookies–when a request to authenticates comes in, the user’s ID is added to the session, and the current user added to the connection’s assigns. A status of :ok is returned to the client (a vue.js app) which then knows we’re authenticated. So far so good.

One problem that I have is that, if the server restarts, the session info is lost, and the client doesn’t know it is no longer authenticated.

The complication here is that often the client will make requests to an endpoint that does not require authentication, so we’re still responding with 200s.

Is there a way for phoenix to intercept the incoming requests and then check to see if the _myapp_key cookie is invalid? In that case I can return a 401, and the client can then redirect to the login page.

1 Like

Which authentication library do you use?

None. Basically wrote it based on the authentication used in Programming Phoenix >= 1.4

This is what the auth code looks like:

# In my controller
  def sign_in(conn, %{"mobile_phone" => mobile_phone, "shortcode" => shortcode}) do
    case Accounts.authenticate_by_mobile_and_shortcode(mobile_phone, shortcode) do
      {:ok, user} ->
        conn
        |> fetch_session()
        |> put_session(:current_user_id, user.id)
        |> assign(:current_user, user)
        |> associate_session_application()
        |> put_status(:ok)
        |> put_view(MyAppWeb.Api.UserView)
        |> render("sign_in.json", user: user)

      {:error, message} ->
        conn
        |> put_status(:unauthorized)
        |> put_view(MyAppWeb.ErrorView)
        |> render("401.json", message: message)
    end
  end
# In my conn
  defp ensure_authenticated(conn, _opts) do
    current_user_id = get_session(conn, :current_user_id)

    cond do
      conn.assigns[:current_user] ->
        conn

      user = current_user_id && Accounts.get_user!(current_user_id) ->
        conn
        |> assign(:current_user, user)

      true ->
        conn
        |> put_status(:unauthorized)
        |> put_view(MyAppWeb.ErrorView)
        |> render("401.json", message: "You do not have permission to access this resource")
        |> halt()
    end
  end