I am attempting to use guardian 0.14 and guardian_db 0.8 with elixir/phoenix. However, I keep running into the following error in the hooks:
[error] #PID<0.983.0> running Api.Endpoint terminated
Server: localhost:4000 (http)
Request: POST /api/login
** (exit) an exception was raised:
** (UndefinedFunctionError) function MyApp.Repo.insert/1 is undefined (module MyApp.Repo is not available)
MyApp.Repo.insert(#Ecto.Changeset<action: nil, changes: %{claims: %{}}, errors: [jwt: {"is invalid", [type: :string, validation: :cast]}], data: #GuardianDb.Token<>, valid?: false>)
lib/guardian_db.ex:87: GuardianDb.after_encode_and_sign/4
(api) web/helpers/guardian_hooks.ex:12: Api.GuardianHooks.after_encode_and_sign/4
(guardian) lib/guardian.ex:89: Guardian.encode_from_hooked/1
(guardian) lib/guardian/plug.ex:183: Guardian.Plug.api_sign_in/4
(api) web/controllers/user_controller.ex:81: Api.UserController.login_user/2
(api) web/controllers/user_controller.ex:1: Api.UserController.action/2
(api) web/controllers/user_controller.ex:1: Api.UserController.phoenix_controller_pipeline/2
(api) lib/api/endpoint.ex:1: Api.Endpoint.instrument/4
(api) lib/phoenix/router.ex:261: Api.Router.dispatch/2
(api) web/router.ex:1: Api.Router.do_call/2
(api) lib/api/endpoint.ex:1: Api.Endpoint.phoenix_pipeline/1
(api) lib/plug/debugger.ex:123: Api.Endpoint."call (overridable 3)"/2
(api) lib/api/endpoint.ex:1: Api.Endpoint.call/2
(plug) lib/plug/adapters/cowboy/handler.ex:15: Plug.Adapters.Cowboy.Handler.upgrade/4
(cowboy) /Users/me/source/proj/proj_api/deps/cowboy/src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4
My code is as follows:
Config
# Guardian config
config :guardian, Guardian,
issuer: "APIAPP",
ttl: { 30, :days },
allowed_drift: 2000,
verify_issuer: true,
secret_key: "SECRETSECRETSECRET",
serializer: Api.GuardianSerializer,
hooks: Api.GuardianHooks
config :guardian_db, GuardianDb,
repo: Api.Repo,
schema_name: "guardian_tokens"
Hooks
defmodule Api.GuardianHooks do
@moduledoc """
Used for hooks for guardian
"""
use Guardian.Hooks
def after_encode_and_sign(resource, claims, token, _options) do
claims = if (claims == nil), do: %{}, else: claims
with {:ok, _} <- GuardianDb.after_encode_and_sign(resource, token["typ"], claims, token) do
{:ok, token}
end
end
def on_verify(claims, token, _options) do
with {:ok, _} <- GuardianDb.on_verify(claims, token) do
{:ok, claims}
end
end
def on_revoke(claims, token, _options) do
with {:ok, _} <- GuardianDb.on_revoke(claims, token) do
{:ok, claims}
end
end
end
Why is it not using the repo I pass to it in the config?
In addition, I dropped a pry in there, and ran GuardianDb.repo
and it returns MyApp.Repo
. It's like it isn't taking my repo config.
guardian_db fetches the value of the
repo
key in the config at compile time, which means you'll need to recompile that package whenever you change the value ofrepo
in your config. This can be done by running the following command: