I’m trying to set up user authentication with Guardian 1.0 for my Phoenix 1.4 Absinthe api. Upon launching the server, I’m confronted with the following error from Graphiql:
# RuntimeError at POST /api
Exception:
** (RuntimeError) `error_handler` not set in Guardian pipeline
(guardian) lib/guardian/plug/pipeline.ex:233: Guardian.Plug.Pipeline.raise_error/1
where my terminal output is:
[error] #PID<0.496.0> running MyAppWeb.Endpoint (connection #PID<0.492.0>, stream id 2) terminated
Server: localhost:4000 (http)
Request: POST /api
** (exit) an exception was raised:
** (RuntimeError)error_handler
not set in Guardian pipeline
(guardian) lib/guardian/plug/pipeline.ex:233: Guardian.Plug.Pipeline.raise_error/1
(guardian) lib/guardian/plug/load_resource.ex:77: Guardian.Plug.LoadResource.return_error/3
(my_app) lib/my_app_web/router.ex:12: MyAppWeb.Router.graphql/2
(my_app) lib/my_app_web/router.ex:1: MyAppWeb.Router.pipe_through1/1
(phoenix) lib/phoenix/router.ex:270: Phoenix.Router.call/1
(my_app) lib/my_app_web/endpoint.ex:1: MyAppWeb.Endpoint.plug_builder_call/2
(my_app) lib/plug/debugger.ex:122: MyAppWeb.Endpoint.“call (overridable 3)”/2
(my_app) lib/my_app_web/endpoint.ex:1: MyAppWeb.Endpoint.call/2
(phoenix) lib/phoenix/endpoint/cowboy2_handler.ex:34: Phoenix.Endpoint.Cowboy2Handler.init/2
(cowboy) /home/spotless/Documents/AbsintheBook/OnlineTutorialBasics/tutorial/my_app/deps/cowboy/src/cowbo
y_handler.erl:41: :cowboy_handler.execute/2
(cowboy) /home/spotless/Documents/AbsintheBook/OnlineTutorialBasics/tutorial/my_app/deps/cowboy/src/cowbo
y_stream_h.erl:296: :cowboy_stream_h.execute/3
(cowboy) /home/spotless/Documents/AbsintheBook/OnlineTutorialBasics/tutorial/my_app/deps/cowboy/src/cowbo
y_stream_h.erl:274: :cowboy_stream_h.request_process/3
(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
I’ve tried including the following line in my :graphql pipeline
plug Guardian.Plug.Pipeline, module: MyApp.Guardian, error_handler: Guardian.Plug.ErrorHandler
but I have not been successful. I’ve been following a tutorial which uses Guardian .14 and Phoenix 1.2, and I’ve been trying to transcribe different pieces of it with help from this community in previous posts. This is the last piece of the tutorial I’ll need help with to get it fully functional, and any help would be greatly appreciated I’ll leave relevant pieces of code below:
/lib/my_app_web/router.ex
defmodule MyAppWeb.Router do
use MyAppWeb, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :graphql do
# plug Guardian.Plug.Pipeline, module: MyApp.Guardian, error_handler: Guardian.Plug.ErrorHandler
plug Guardian.Plug.VerifyHeader, realm: "Bearer"
plug Guardian.Plug.LoadResource
plug MyAppWeb.Context
end
scope "/", MyAppWeb do
pipe_through :browser
get "/", PageController, :index
end
scope "/api" do
pipe_through :graphql
forward "/", Absinthe.Plug,
schema: MyAppWeb.Schema
end
forward "/graphiql", Absinthe.Plug.GraphiQL,
schema: MyAppWeb.Schema
end
/lib/my_app/guardian.ex
defmodule MyApp.Guardian do
use Guardian, otp_app: :my_app
alias MyApp.Repo
alias MyApp.User
def subject_for_token(user=%User{}, _claims) do
{:ok, "User:#{to_string(user.id)}"}
end
def resource_from_claims(claims) do
"User: " <> user_id = claims["sub"]
case Repo.get(User, user_id) do
%User{} = user -> {:ok, user}
_ -> {:error, :reason_for_error}
end
end
end
/lib/my_app_web/plugs/context.ex
defmodule MyAppWeb.Context do
@behaviour Plug
import Plug.Conn
def init(opts), do: opts
def call(conn, _) do
case Guardian.Plug.current_resource(conn) do
nil -> conn
user -> put_private(conn, :absinthe, %{context: %{current_user: user}})
end
end
end
Thanks in advance for any feedback!