This repository was archived by the owner on Jul 25, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 45
How to do authentication and authorization in a Phoenix application with GraphQL
Sean Abrahams edited this page Mar 16, 2016
·
11 revisions
1. Setup plug_graphql
defmodule YourApp.Plugs.Authenticate do
import Plug.Conn
import Phoenix.Controller
def init(default), do: default
def call(conn, _default) do
user_id = get_session(conn, :user_id)
if user_id do
user = YourApp.Repo.get!(YourApp.User, user_id)
conn = assign(conn, :current_user, user)
# Set user in conn.assigns.graphql_options for GraphQL queries/mutations
# graphql_plug will look for `conn.assigns[:graphql_options][:root_value]` and include it in the GraphQL context variable
graphql_options = Map.merge(conn.assigns[:graphql_options] || %{}, %{ root_value: %{ user: user } })
conn = assign(conn, :graphql_options, graphql_options)
conn
else
conn
|> put_flash(:error, 'You need to be signed in to view this page.')
|> redirect(to: "/")
end
end
end
This plug will redirect users who are not logged in (don't have a :user_id set in their session) to your root page with a flash error message.
Users who are logged in will have their user object added to the conn[:assigns]
map and the conn[:assigns][:graphql_options][:root_value]
. We add it to the conn[:assigns][:graphql_options][:root_value]
map because that's where plug_graphql
needs it to be.
pipeline :api do
plug :accepts, ["json"]
plug :fetch_session
plug YourApp.Plugs.Authenticate # Require users to be logged in to access API
end
scope "/graphql" do
pipe_through :api
get "/", GraphQL.Plug.Endpoint, schema: {GraphQL.Schema.Root, :schema}
post "/", GraphQL.Plug.Endpoint, schema: {GraphQL.Schema.Root, :schema}
end
plug_graphql
will then make it available in your GraphQL resolve functions (3rd argument) which you can then use for authorization.
For example:
defmodule TestSchema do
def schema do
%GraphQL.Schema{
query: %GraphQL.Type.ObjectType{
name: "Hello",
fields: %{
greeting: %{
type: %GraphQL.Type.String{},
args: %{
name: %{
type: %GraphQL.Type.String{}
}
},
resolve: fn(obj, args, info) ->
### HERE
info[:root_value][:user]
end
}
}
}
}
end
end