Middleware Authorization
Learn how to add authorization checks using middleware.
We'll cover the following...
Authorization middleware
Adding authorization checks inside all our resolvers will produce clutter, so let’s build middleware to handle this problem fully. As you may recall, we have two choices for how to apply middleware:
.We can use the middleware/2
macro to configure individual fields or the middleware/3
callback function to take a pattern-based approach. Different fields have slightly different authorization conditions, so we will use the middleware/2
macro to annotate them individually. Using this middleware should look something like this:
field :create_menu_item, :menu_item_result doarg :input, non_null(:menu_item_input)middleware Middleware.Authorize, "employee"resolve &Resolvers.Menu.create_item/3end
Then, in the resolver, we can just go back to how it was before the authorization check:
def create_item(_, %{input: params}, _) dowith {:ok, item} <- Menu.create_item(params) do{:ok, %{menu_item: item}}endend
Note: We no longer need to check the type of the
current_user
in the resolution function or handle the possibility that there is nocurrent_user
at all. The middleware will handle all of this for us.
defmodule PlateSlateWeb.Schema.Middleware.Authorize do@behaviour Absinthe.Middlewaredef call(resolution, role) dowith %{current_user: current_user} <- resolution.context,true <- correct_role?(current_user, role) doresolutionelse_ ->resolution|> Absinthe.Resolution.put_result({:error, "unauthorized"})endenddefp correct_role?(%{}, :any), do: truedefp correct_role?(%{role: role}, role), do: truedefp correct_role?(_, _), do: falseend
By specifying @behaviour ``Absinthe.Middleware
, the compiler will ...