I have a custom plug which does not appear to be called in its pipeline. The plug DxAppRcWeb.CheckAuth is meant to be my auth solution for a specific endpoint on my API. None of the IO is triggering in my console for requests to this endpoint. The API is otherwise responding appropriately to graphql calls on this endpoint.
Router File:
defmodule DxAppRcWeb.Router do
use DxAppRcWeb, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_live_flash
plug :put_root_layout, {DxAppRcWeb.Layouts, :root}
plug :protect_from_forgery
plug :put_secure_browser_headers
end
scope "/", DxAppRcWeb do
pipe_through :browser
live "/", HomeLive
live "/organizations", OrganizationLive
live "/create-organization", CreateOrganizationLive
end
pipeline :auth do
plug :accepts, ["json"]
forward "/auth", DxAppRcWeb.AuthWrapper, schema: DxAppRcWeb.AuthSchema
end
pipeline :api do
plug :accepts, ["json"]
plug DxAppRcWeb.CheckAuth
forward "/api", Absinthe.Plug, schema: DxAppRcWeb.Schema
end
end
Auth Module:
defmodule DxAppRcWeb.CheckAuth do
import Plug.Conn
alias DxAppRc.Auth.MockCheckAuth
def init(_default), do: IO.puts("Auth Plug Init")
def call(conn, opts) do
IO.puts("Calling Auth Plug...")
check_auth(conn, opts)
end
def check_auth(conn, _opts) do
IO.puts("Calling Check Auth...")
auth_token = conn |> get_req_header("authorization")
IO.inspect(auth_token, label: "Auth Token")
validate_auth_token(conn, auth_token)
end
# ... Other business logic
end
This is the most confusing part to me, because I don’t see any pipe_through statements using :api or :auth at all, but Absinthe.Plug is in pipeline :api. Maybe something important got trimmed when posting the code?
To expand on what @al2o3cr was alluding to, routes e.g. forward, get, etc. generally go inside of scope blocks and not pipeline blocks. Here’s an example from the docs: Routing — Phoenix v1.7.1.
pipeline :browser do
...
end
pipeline :auth do
plug HelloWeb.Authentication
end
scope "/" do
pipe_through [:browser]
get "/reviews", PostController, :index
get "/reviews/:id", PostController, :show
end
scope "/" do
pipe_through [:browser, :auth]
get "/reviews/new", PostController, :new
post "/reviews", PostController, :create
end
So maybe something like this is what you intended:
pipeline :api do
plug :accepts, ["json"]
end
pipeline :auth do
plug DxAppRcWeb.CheckAuth
end
scope "/" do
pipe_through [:api, :auth]
forward "/api", Absinthe.Plug, schema: DxAppRcWeb.Schema
end
scope "/" do
pipe_through [:api]
forward "/auth", DxAppRcWeb.AuthWrapper, schema: DxAppRcWeb.AuthSchema
end
Also yes - it is sending a connection back (verifying with inspect).
Also, the error is:
** (UndefinedFunctionError) function DxAppRcWeb.Absinthe.Plug.init/1 is undefined (module DxAppRcWeb.Absinthe.Plug is not available)
DxAppRcWeb.Absinthe.Plug.init([schema: DxAppRcWeb.Schema])
(phoenix 1.7.1) lib/phoenix/router/route.ex:42: Phoenix.Router.Route.call/2
(phoenix 1.7.1) lib/phoenix/router.ex:425: Phoenix.Router.__call__/5
(dx_app_rc 0.1.0) lib/dx_app_rc_web/endpoint.ex:1: DxAppRcWeb.Endpoint.plug_builder_call/2
The Absinthe Plug isn’t building properly. This is confusing to me, as when I include the forward statement in the pipeline, this error does not happen and the GraphQL endpoint works as it should. This tells me that my schema is good, that my dependencies are good, and that there is some level of configuration is proper.
Hmm, it looks like it’s forwarding to the wrong module because of the scope. I’m guessing it needs to call Absinthe.Plug and not DxAppRcWeb.Absinthe.Plug. So maybe try something like this?
scope "/", Absinthe do
pipe_through :api
forward "/api", Plug, schema: DxAppRcWeb.Schema
end
pipeline :api do
plug :accepts, ["json"]
plug DxAppRcWeb.CheckAuth
end