0

I have Absinthe middleware that checks the context for an authenticated user, like so:

defmodule CliftonWeb.Middlewares.CheckAuth do
  @behaviour Absinthe.Middleware
  require Logger

  def call(resolution, _config) do
    case resolution.context do
      %{current_user: _} ->
        resolution
      _ ->
        resolution
        |> Absinthe.Resolution.put_result({:error, "unauthenticated"})
    end
  end
end

This is then applied in my schema:

defmodule CliftonWeb.Schema do
  # Imports and plugin setup etc...


  def middleware(middleware, _field, %{identifier: :student_queries} = object) do
    [CliftonWeb.Middlewares.CheckAuth | middleware ]
  end

  def middleware(middleware, _field, object), do: middleware

  query do
    import_fields :student_queries
    # etc...
  end

end

However the middleware is never called when I make a query. Is it possible to match on any identifier, or only query, mutation etc?

In addition, is this the best way to only apply middlewares to certain groups of queries/mutations?

Tom Haines
  • 123
  • 3
  • 9

2 Answers2

0

There is no way to match on groups imported using import_fields in the middleware/2 callback. You could look into setting __private__ flags on the objects/fields and see if you can match on that.

0

For applying middleware, im using middleware/2 macro which would apply middleware to only that query, i dont need to apply on every field of every object.

For authentication, you can follow the guide in documentation which is using Plug. In your router, you can pipe_through [:optional_auth, :graphql_context], :optional_auth will load the resource if its present and doesnt restrict otherwise while :graphql_context just adds the user to the current context. Now where your resolver functions are defined, you can pattern match as:

def resolver_func(_, _args, %{current_user: _user}), do: # for authenticated user

def resolver_func(_, _args, _), do: {:error, :unauthenticated}

I dont know about the best way but this is another way to handle authentication.