Authentication and authorization are very complex topics for any public-facing application. Unless you want to make every piece of data and every possible action public (does something like this even exist?!), you're forced to implement both processes mentioned earlier into your software. However, using Dgraph, we can vastly simplify these complex topics and implement them in about 20 minutes.
This tutorial assumes that you understand the basics of GraphQL schema. If you don't, please read The 10 Minute Introduction to GraphQL Schema.
Authentication vs. Authorization
Before continuing, let's understand the difference between authentication and authorization.
Authentication: The authentication service or layer identifies users based on the credentials they provide. If the credentials are valid, the user is authenticated.
Authorization: The authorization layer checks if the authenticated users can access the resources or perform the actions they are trying to access/perform.
General Authentication + Authorization Flow
First, let's cover the basics of the auth+auth flow using Dgraph. ![](upload://nFYDEgq2pmTkmIXRxM09fcLHwwy.png)
As you can see in the image above, the frontend acts as the middleman between the authentication service and Dgraph (which includes the authorization layer).
The magic starts with the frontend. The frontend asks users to authenticate with the authentication service (either a service like Auth0 or a custom service). The authentication service returns a JWT with claims to allow our authorization service to understand who is requesting access. The frontend includes this JWT with every request. Once Dgraph gets a request, it validates the JWT. It then opens up the custom claims and injects the values into the authorization rules defined in our schema. Finally, Dgraph returns the appropriate data based on whether the authorization rules pass or fail.
Adding Authorization to your Schema Adding authorization to your schema is done with two parts:
Enabling Authorization
The first step to adding authorization is to enable authorization using the Dgraph.Authorization
comment. Add this comment to the end of your schema.
# Dgraph.Authorization {"VerificationKey":"","Header":"","Namespace":"","Algo":"","Audience":[]}
Note: The space between #
and Dgraph.Authorization
is essential.
Let's understand what each of the arguments above means:
-
VerificationKey
: This is the public key (Can also be the secret key). Used to verify your JWT -
Header
: The header that includes the JWT in each request. -
Namespace
: The namespace is the field in the JWT that includes our custom claims. -
Algo
: The algorithm that your key is using. -
Audience
: A list of valid audiences. Used to validate the JWT.
The @auth Directive
We've enabled authorization, and now we need to create authorization rules using the @auth
directive.
Let's use the example of a todo app. We'll start with the schema below:
type Todo {
id: ID!
value: String! @search(by: [fulltext])
completed: Boolean! @search
user: User
}
type User {
username: String! @id @search(by: [hash])
name: String @search(by: [exact])
todos: [Todo] @hasInverse(field: user)
}
We want to lock down the Todo
type, and only allow users to see Todo
s that they've created.
What we'll do is add a rule that pulls a field from the JWT claims. USER
is the field we will use, and it will contain the user's username. Then, we'll create a query that uses this field to pull Todo
s that are created by a User
with a username equal to our USER
field.
type Todo @auth(
query: { rule: """
query($USER: String!) {
queryTodo {
user(filter: { username: { eq: $USER } }) {
__typename
}
}
}"""}), {
id: ID!
value: String! @search(by: [fulltext])
completed: Boolean! @search
user: User!
}
type User {
username: String! @id @search(by: [hash])
name: String @search(by: [exact])
todos: [Todo] @hasInverse(field: user)
}
As you can see, we added a query
rule. There are four types of rules: query
, add
, update
and delete
. Each one corresponds to a different kind of action. Our query rule locks down any form of query on the Todo
type.
As you can see, it's effortless to add authorization to our schema. To read more about authorization, take a look at the authorization documentation.
ReferencesTop image: SpaceX Demo-2: A New Era in Human SpaceflightThis is a companion discussion topic for the original entry at https://dgraph.io/blog/post/slash-intro-to-auth/