elixirphoenix-framework

Cannot get current user with guardian


I'm using Guardian and trying to use Canary however, I can't seem to fetch the current user, canary needs the current_user in conn.assigns, I've followed this, if I ask for (inside a controller action):

Guardian.Plug.authenticated?(conn)

I get true, but if I do:

Guardian.Plug.current_resource(conn)

It's just blank.

I have this code in my api pipeline:

pipeline :private_api do
  plug :accepts, ["json"]
  plug Guardian.Plug.LoadResource
  plug Guardian.Plug.VerifyHeader

  plug Guardian.Plug.EnsureAuthenticated, handler: SessionController
  plug MyApp.Plug.CurrentUser
end    

and in for MyApp.Plug.CurrentUser

defmodule MyApp.Plug.CurrentUser do
  def init(opts), do: opts

  def call(conn, _opts) do
    current_user = Guardian.Plug.current_resource(conn)
    Plug.Conn.assign(conn, :current_user, current_user)
  end
end

Session create method:

 def create(conn, %{"session" => session_params}) do
    case MyApp.Session.authenticate(session_params) do
      {:ok, user} ->
        {:ok, jwt, _full_claims} = user |> Guardian.encode_and_sign(:token)

        Plug.Conn.assign(conn, :current_user, user)

        conn
        |> put_status(:created)
        |> render("show.json", jwt: jwt, user: user)

      :error ->
        conn
        |> put_status(:unprocessable_entity)
        |> render("error.json")
    end
  end

Maybe I'm just missing something.


Solution

  • While not ideal, this was my solution, this question does not accept more answers since it is way too old to even validate that the answers work:

    defmodule MyApp.Plug.CurrentUser do
      alias MyApp.GuardianSerializer
      def init(opts), do: opts
    
      def call(conn, _opts) do
        current_token = Guardian.Plug.current_token(conn)
        case Guardian.decode_and_verify(current_token) do
          {:ok, claims} ->
            case GuardianSerializer.from_token(claims["sub"]) do
              {:ok, user} ->
                Plug.Conn.assign(conn, :current_user, user)
              {:error, _reason} ->
                conn
            end
          {:error, _reason} ->
            conn
        end
      end
    end