I use the built-in GraphiQL interface in Absinthe. As follows:
pipeline :browser do
plug RemoteIp, headers: ~w[x-forwarded-for], proxies: ~w[]
plug :accepts, ["html", "json"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
end
scope "/graphiql" do
pipe_through :browser # Use the default browser stack
forward "/", Absinthe.Plug.GraphiQL,
schema: ApiWeb.Schema,
default_headers: {__MODULE__, :graphiql_headers},
context: %{pubsub: ApiWeb.Endpoint}
end
def graphiql_headers(conn) do
%{
"X-CSRF-Token" => Plug.CSRFProtection.get_csrf_token(),
}
end
I need the end-user to insert an Authentication: Bearer <JWT>
in the interface, and then need to unwrap it for the sub: header, which contains my user id, which I need to use in the resolvers.
The user can configure custom headers, that's no problem. If he then executes a GraphSQL query, the interface will issue a POST to the /graphiql endpoint. It is at this point I want to invoke a few plugins which check the JWT and retrieve user info.
I thought I could use the default_headers option, but that seems only to be invoked during GET requests.
It seems I need different pipelines for GET and POST to the /graphiql endpoint, how do I accomplish that? I must be doing something wrong...
Note that if I use the same pipeline for GET and POST, the JWT will already be checked on just visiting the endpoint in the browser, which I don't want.