Can't fetch user with get_session

I followed and got good results until lesson 8 of https://www.youtube.com/watch?v=XVeCkV8KBuU&t=489s
With a slight tweak of having Users and Accounts as one entity: Users
I always got the unauthorized error despite IO.inspect conn showing everything in place

Set user file:

defmodule InvoiceApiWeb.Auth.SetUser do

    import Plug.Conn
    alias InvoiceApiWeb.Auth.ErrorResponse
    alias InvoiceApi.Users

    def init(_options) do 

    end

    def call(conn , _options) do 

        if conn.assigns[:user] do
            conn
        else
            user_id = get_session(conn, :user_id)

            if user_id == nil, do: raise ErrorResponse.Unauthorized

            user = Users.get_user!(user_id)

            cond do
                user_id && user -> assign( conn, :user, user)
                true -> assign(conn, :user, nil)
            end
        end
    end
end

IO.inspect conn result

%Plug.Conn{
 ...
    :guardian_default_resource => %InvoiceApi.Users.User{
      meta: #Ecto.Schema.Metadata<:loaded, "users">,
      id: "ad5fb566-f641-47ee-8505-4a3f48b92c4d",
      name: "Mustafa Safa",
      email: "mustsafa@gmail.com",
      hash_password: "$argon2id$v=19$m=65536,t=3,p=4$4F4Kyj47TUVS/8DIOpdgjw$uygyB0ppRJfGIjwwZd+HEysBeuCSvEZLRij3cRa+9OA",
      invoice: #Ecto.Association.NotLoaded<association :invoice is not loaded>,
      inserted_at: ~U[2025-03-12 14:38:41Z],
      updated_at: ~U[2025-03-12 14:38:41Z]
    }
}

:plug_session_fetch => :done,
:plug_session => %{},
:before_send => [#Function<0.9035112/1 in Plug.Session.before_send/2>,

as an additional note in IO.inspect conn

I don’t know why my plugs here are empty

Interestingly, I can’t create another account as long as plug :fetch_session is in my router api pipeline

NVM, last error was just a JSON structure error

Since you’re always seeing the unauthorized error, I’d suggest double checking that :user_id is set in the session.

Updated to add: If you search for put_session in the tutorial repo, you’ll see how :account_id is set in the accounts controller when creating and refreshing a session so that it can be fetched from the session in the auth plug.

NEWS FLASH!

Caught the error,

It’s simply Ecto/Elixir not converting strings properly.

How do I enforce it for I can’t interpolate in parameters?

set_session.ex in get_session is where the string interpolation fails

Not sure what your screenshot is supposed to demonstrate. I can only see you are pasting an UUID without properly enclosing it in double quotes first. And then you changed that in the next iex line.

What’s the problem?

1 Like

Looking back into my conn struct, I found this

resp_headers: [
{“cache-control”, “max-age=0, private, must-revalidate”},
{“x-request-id”, “GC3pR-dSGGtgDfUAAAaE”}
],

Why should I revalidate and how come he didn’t ran into the same problem in vid?

After spamming IO.inspect a bit, I found out it doesn’t even print at the beginning of the show function and I still get 401 from Guardian.

I’m getting restricted by guardian at the router level despite checking that file twice.

Meanwhile, in my router.ex

defmodule InvoiceApiWeb.Router do
use InvoiceApiWeb, :router
use Plug.ErrorHandler

defp handle_errors(conn, %{reason: %Phoenix.Router.NoRouteError{message: >message}}) do
conn |> json(%{errors: message}) |> halt()
end

defp handle_errors(conn, %{reason: %{message: message}}) do
conn |> json(%{errors: message}) |> halt()
end

pipeline :api do
plug :accepts, [“json”]
plug :fetch_session
end

pipeline :auth do
plug InvoiceApiWeb.Auth.Pipeline
plug InvoiceApiWeb.Auth.SetUser
end

scope “/api”, InvoiceApiWeb do
pipe_through :api
post “/users/create”, UserController, :create
post “/users/sign_in”, UserController, :sign_in
end

scope “/api”, InvoiceApiWeb do
pipe_through [:api, :auth]
get “/users/by_id/:id”, UserController, :show
end

end

I tried IO.inspect conn on first the user_controller.ex and then set_user.ex

:plug_session has :user_id in the controller but forgets it afterwards in set_session

Nevermind, it was an issue with Hopscotch API for desktop being outdated and the web version which was recently updated worked flawlessly