Elixir, Phoenix, Guardian - aaargh stuck with strange error

Hello,
I’m trying to get guardian to work in a phoenix/elixir web application. Have hit an error which google is providing no help for… don’t know if this is the place to ask… if not please redirect me.

OK, so i have a simple phoenix application, and want to protect it with login, i found comeonin and guardian and followed a tutorial… got most of the way through they hit a wall.

When i call Guardian.Plug.sign_in(user, :access) i get an error…

[error] #PID<0.544.0> running Requester.Endpoint terminated
Server: 10.0.0.192:4000 (http)
Request: POST /sessions
** (exit) an exception was raised:
    ** (CaseClauseError) no case clause matching: :ok
        (guardian) lib/guardian.ex:100: Guardian.encode_from_hooked/1
        (guardian) lib/guardian/plug.ex:117: Guardian.Plug.sign_in/4
        (requester) web/controllers/auth.ex:11: Requester.Auth.login/2
        (requester) web/controllers/auth.ex:33: Requester.Auth.login_by_username_and_password/4

I’ve tried various things, different keys, different calls (api_sign_in) with and without extra arguments all with no success. The tutorial i was following is…

Setup is.

mix deps - output sanitised a bit to make it shorter
locked at 0.0.1 (base64url) 36a90125
locked at 1.0.4 (connection) a1cae722
locked at 0.9.2 (fs) ed17036c
locked at 0.13.0 (gettext) daafbddc
locked at 1.8.0 (jose) 1ee027c5
locked at 1.2.1 (ranch) a6fb992c
locked at 1.5.1 (poolboy) 6b461639
locked at 1.3.1 (decimal) 157b3ced
locked at 2.2.0 (poison) 4763b69a
locked at 2.6.0 (comeonin) 74c28833
locked at 1.1.0 (db_connection) b2b88db6
locked at 1.0.1 (phoenix_pubsub) c10ddf62
locked at 1.0.2 (cowlib) 9d769a1d
locked at 1.0.4 (cowboy) a324a8df
locked at 1.1.6 (uuid) 4927232f
locked at 1.0.1 (mime) 05c39385
locked at 1.3.0 (plug) 6e2b01af
locked at 2.9.2 (phoenix_html) 371160b3
locked at 1.2.1 (phoenix) 6dc59224
locked at 1.0.6 (phoenix_live_reload) 4490d588
locked at 0.14.1 (guardian) af546385
locked at 0.13.0 (postgrex) e101ab47
locked at 2.1.2 (ecto) 8d7bde41
locked at 3.2.1 (phoenix_ecto) 6cf11d59

config - this has been through a few iterations, none of which made any difference

config :guardian, Guardian,
  allowed_algos: ["HS256","HS512"],
#  verify_module: Guardian.JWT,
  issuer: "Requester.#{Mix.env}",
  ttl: { 30, :days},
  verify_issuer: true,
#  secret_key: to_string(Mix.env),
  secret_key: %{"k" => "5Fn8i7r5cRWZW_yyr9Flkg", "kty" => "oct"},
  serializer: Requester.GuardianSerializer,
  #hooks: GuardianDb,
  permissions: %{
    default: [
      :read_profile,
      :write_profile,
      :read_token,
      :write_token,
    ]
  }

And the offending bit of code is… again this has been through numerous iterations and is s bit messy at present

  def login(conn, user) do
    IO.puts("Hello")
    IO.inspect(user)
    conn
#    |>  Guardian.Plug.sign_in(user, :token, perms: %{default: Guardian.Permissions.max})
#    |> Guardian.Plug.api_sign_in(user,:access,%{claims: "i", make: true, key: :secret})
    |> Guardian.Plug.sign_in(user, :access)
    IO.inspect(conn)
  end

  def verify_username_and_password(name, pass, opts) do
    repo = Keyword.fetch!(opts, :repo)
    user = repo.get_by(Requester.User, username: name)
    cond do
      (user && checkpw(pass, user.password_hash)) ->
        {:ok, user}
      user ->
        {:error, :unauthorized}
      true ->
        dummy_checkpw()
        {:error, :not_found}
    end
  end

  def login_by_username_and_password(conn, name, pass, opts) do
    case verify_username_and_password(name, pass, opts) do
      {:ok, user} ->
        conn
        |> login(user)
        {:ok, conn}
      {:error, _message} ->
        {:error, conn}
    end

the serializer looks like this…

  def for_token(user = %User{}) do
     IO.inspect("for token")
     IO.inspect(user)
     { :ok, "User:#{user.id}" }
  end
  def for_token(_), do: { :error, "Unknown resource type" }

  def from_token("User:" <> id), do: { :ok, Repo.get(User, id) }
  def from_token(_), do: { :error, "Unknown resource type" }

As you can see i’ve added a few IO.put/IO.inspect so i can see what’s happening at various points. The sign_in call hits the for_token routine then drops into Guardian specific code i can’t see and eventually goes boom in encode_from_hooked.

Anyone any ideas? or alternate places to look?

Thanks

I had the same problem after updating Guardian. I did some digging and found this issue which was closed recently and seems to have fixed the problem.

Just to test, I added Guardian to my project using the {:guardian, github: "ueberauth/guardian"} in place of {:guardian, "~> 0.14.1"} and my authentication was once again working like normal.

I guess the fix hasn’t made its way to hex.pm yet. So either downgrade Guardian, use github, or wait a little longer for the changes to make their way to hex.pm

:slight_smile:

2 Likes

I shall give that a whirl, thanks :slight_smile:

Sorted now, 0.14.2 is out with the fix, and the work around above also works. Thanks

1 Like