2019-11-08

Authentication with Hasura

elitasson's avatar on Twitter
Johan Eliasson

Hasura gives you instant GraphQL on PostgreSQL. It's one of the best backend to build web and mobile apps.

But almost every app must handle its users. Users who register, signs in and interact with data in your app. When a request is sent to your backend you must make sure your backend knows who is actually sending the request. Who is the user who sends the request? The backend must know this because your backend will either allow, filter or deny the request.

Why is authentication important with Hasura? Let's say you have some users in a users table.

idusername
1Batman
2Robin
3Catwoman

And you have some data in a private_posts table:

idprivate_postuser_id
1Today I made breakfast.3
2Wow, amazing walk in the sun.1
3Interesting book this 1984.2

Since these are private posts a post should only be available to the user who wrote the private post. Users do not want to share these posts.

This means that every request for private_posts must include some sort of authentication so the backend knows who is actually sending the request.

query {
  private_posts {
    id
    private_post
  }
}

GraphQL request to get all private posts

So, if you just send a request for getting all private posts, without providing details of who you are, the backend won't be able to help you.

Batman did not provide any authentication details in his request. The user must first authenticate. Your app needs to handle authentication.


What is the difference between authentication and authorization?

Authentication is about WHO you are.

Example: I am Batman with user id 1.

Authorization is about WHAT you are allowed to do.

Example: You are only allowed to read private_posts where user_id matches your user id.


This blog post is about authentication.

There are two ways to handle authentication with Hasura. Either with a webhook or with a JWT token.

Webhook

GraphQL request using webhook (Credit: Hasura Docs)
GraphQL request using webhook (Credit: Hasura Docs)

When Hasura receives a request Hasura sends a http request (webhook) to another service that resolves the request and return specific Hasura session variables. The webhook resolves the request based on request headers.

The webhook can be set up with as a web server or cloud functions. Remember that Hasura will make a http request for every request coming to Hasura.

JWT Token

GraphQL request using JWT (Credit: Hasura Docs)
GraphQL request using JWT (Credit: Hasura Docs)

The approach with a JWT token is a bit different. Here, the user first signs in to receive a JWT token. The JWT token is then used in every GraphQL request to Hasura.

A JWT token contains specific user information that has been digitally signed with a shared secret. The secret is shared between the service that creates the JWT token (auth service) and the backend (Hasura).

This means that Hasura can verify and trust the information in the JWT token. In the JWT token information about roles, user id and other user specific information can be stored.

Example JWT token:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwczovL2hhc3VyYS5pby9qd3QvY2xhaW1zIjp7IngtaGFzdXJhLWFsbG93ZWQtcm9sZXMiOlsidXNlciJdLCJ4LWhhc3VyYS1kZWZhdWx0LXJvbGUiOiJ1c2VyIiwieC1oYXN1cmEtdXNlci1pZCI6ImM4ZWU4MzUzLWI4ODYtNDUzMC05MDg5LTYzMWVhN2ZkNGM4YSJ9LCJpYXQiOjE1NzM2MzczMDMsImV4cCI6MTU3MzYzODIwM30.aOS1lc1ThOvvesvtL7ejqPSU98rQsU-dgk4sLZmtQmU
JWT token to the left. Decoded information to the right.
JWT token to the left. Decoded information to the right.

The JWT token must contain specific claims in the payload. These claims includes information about the user. Ex:

x-hasura-allowed-roles
x-hasura-default-role
x-hasura-user-id
x-hasura-company-id

Based on these claims, fine grained permission rules (authorization) can be set up in Hasura.

Permissions based on JWT claims.
Permissions based on JWT claims.

That was an overview of authentication in Hasura. What it is, how it works and different approaches.

There are actually two more ways to access data with Hasura and GraphQL. Unauthenticated access and the x-hasura-admin-secret HTTP header.

Unauthenticated access

You can provide an unauthenticated access role with Hasura. This role can be assigned to users without signing in and you can use this role to make permissions in your Hasura console. This is good for public data that should be freely accessable for anyone.

The role is defined using the HASURA_GRAPHQL_UNAUTHORIZED_ROLE environment variable. For example, you could name the role public (default value for new Nhost projects).

x-hasura-admin-secret

You might have noticed that in the GraphiQL section in the Hasura console there are a special x-hasura-admin-secret available. This is a special header which gives you full admin access to every part of the GraphQL API. The admin secret and the x-hasura-admin-secret should only every be used in the Hasura console or in very secure environments. They should generally never be used in in your app client side.

To use the x-hasura-admin-secret simply add a header with key x-hasura-admin-secret and your admin secret as value. The admin secret is the same secret you use to log in to the Hasura console.

That's it. We have now covered on a high level the different approaches of authentication with Hasura.

Try Nhost for Free Today

Get a perfect backend with Hasura
Get started