Jenaro Calvino

Serverless Auth | Netlify + Hasura

Estimated reading time: 3 minutes, 9 seconds.

Story

I was working on a small side project where I needed to set up authentication and I wanted to go with a serverless approach, after reading a lot on Hasura's docs I couldn't find an easy approach without involving Auth0, Firebase or another authentication provider, and all I wanted was old fashioned JWT authentication.

Hasura docs are really good and I will be linking them all through the post, I am not trashing on their docs

Stack

React Hasura Netlify

Hasura

Hasura let's you build a back end without writing any code, it is super easy to set up and it takes no time.

Go to https://hasura.io > create an account > create a new project

Follow the docs on how to create the project, the only place where I had to differ was setting the environment variables and permissions.

Screenshot

The ones to pay attention to are:

  • HASURA_GRAPHQL_UNAUTHORIZED_ROLE (which according to Hasura it can be changed to anything you want but it didn't work for me until I changed it back to anonymous)
  • HASURA_GRAPHQL_JWT_SECRET follow this link to read more about this variable but basically I used HSA256 as the type of the JWT and made a random 32 chars key. It will look like something like this:
{"key":"random 32 chars","type":"HSA256"}

Connect to or create a database

After creating the new database we can go to create new table and create the users table, this is how my users table looks:

Screenshot

Then, let's add the permissions (docs), we need to set the role anonymous to be able to insert to and read from the table.

Back to the API tab, we can remove the header x-hasura-admin-secret and set x-hasura-role: anonymous. It should update the schema and only show you what queries and mutations that role can make. I chose to go with a REST implementation instead of GraphQL, so I made the following query to insert a user

mutation RegisterUser($email: String, $password: String) {
  insert_users(objects: {email: $email, password: $password}) {
    returning {
      email
      id
    }
  }
}

and then clicked on the tab REST on the top left of the screen, that will allow you to set REST endpoints, I chose to make the method POST and it will receive an object with email and password as keys.

For the login I made another endpoint but with the query

query MyQuery($email: String) {
  users(where: {email: {_eq: $email}}) {
    password
    email
  }
}

and I made this one a GET where the route ends with /:email which makes it available on the query.

Front end

What you are building your front end on doesn't actually matter, we will be using Netlify's serverless functions to connect to the Hasura generated endpoint.

We need to install the following dependencies:

  • bcrpyt
  • jsonwebtoken
  • isomorphic-fetch (or any lib for fetching that you like)
  • netlify-cli (dev dependency)

On the root of you project create a file called netlify.toml and it should contain the following:

[build]
  functions = "functions/"

Now create a folder called functions also on the root of the project and add two js files inside, login.js and register.js.

Now fetching the urls /.netlify/functions/name-of-file will actually run the serverless function inside the file.

I created two gists, one for each file

Now all you need is to create the frontend however you like, and two forms, one to login and another to register, set the permissions for the user role and you'll be able to query when setting the

{ Authorization: `Bearer ${tokenYouJustCreated}` }

header. Of course don't forget to add the header, Hasura will automatically interpret the JWT and only allow the queries you added on the permissions.