loading...
Hasura

Adding Authentication to Hasura and Gatsby web app with Auth0

vladimirnovick profile image Vladimir Novick ・3 min read

A while ago we live-streamed a live coding event with Jason Lengstorf on how to create a real-time web app with Gatsby and Hasura.
If you are not familiar with Hasura, check this blog post:

In that live stream, we've created Gatsby static web app and added cool real-time capabilities using GraphQL Subscriptions. For this task, we live coded GraphQL server using Hasura.

During that stream I haven't covered auth though, so recently we decided to do another live stream with Jason to close this gap.

In this stream, we haven't covered Gatsby setup, but we covered authentication solution with Hasura using Auth0. I also wrote about other auth methods in my blog post Hasura Authentication Explained, but for Auth0 steps will be as following:

Setting Auth0 domain

Go to auth0.com and sign in or sign up if you don't have an account yet. After logging in, you will get to Dashboard screen. There, you need to create your app.


We will choose a Single page application and after we create our app, we can choose how to integrate Auth0 into our web app.

I won't cover this step, because it is pretty self-explanatory and it is well documented in Auth0 console. An important part is that we need to path Authorization: Bearer token to our GraphQL API.

Setting our Hasura with Auth0

Now, when we pass proper auth token to Hasura, there are several steps that we need to do:

  • On Signup, we need to execute mutation on Hasura endpoint and insert a new user with Auth0 user id. This can be done by using Auth0 rules. From our Dashboard we navigate to the Rules tab and create a new rule. The code for this rule will be:
function (user, context, callback) {
  const userId = user.user_id;
  const nickname = user.nickname;

  const admin_secret = "adminsecret";
  const url = "https://myendpoint/v1/graphql";
  request.post({
      headers: {'content-type' : 'application/json', 'x-hasura-admin-secret': admin_secret},
      url:   url,
      body:    `{\"query\":\"mutation($userId: String!, $nickname: String) {\\n          insert_users(\\n            objects: [{ id: $userId, name: $nickname }]\\n            on_conflict: {\\n              constraint: users_pkey\\n              update_columns: [last_seen, name]\\n            }\\n          ) {\\n            affected_rows\\n          }\\n        }\",\"variables\":{\"userId\":\"${userId}\",\"nickname\":\"${nickname}\"}}`
  }, function(error, response, body){
       console.log(body);
       callback(null, user, context);
  });
}

Here we will be using Hasura admin secret for server to server communication.

Remember - never use admin secret on the client

  • Before our token is generated, we need to add so-called custom claims to JWT token, so Hasura will be able to get required info from JWT Token. So what we need to do is create another rule with the following code:
function (user, context, callback) {
  const namespace = "https://hasura.io/jwt/claims";
  context.idToken[namespace] = 
    { 
      'x-hasura-default-role': 'user',
      'x-hasura-allowed-roles': ['user'],
      'x-hasura-user-id': user.user_id
    };
  callback(null, user, context);
}
  • Last and final step will be adding HASURA_GRAPHQL_JWT_SECRET as environment variable for Hasura. To generate config, you can use the following tool: https://hasura.io/jwt-config

Summary

You can read more about Authentication and Permissions in my previously mentioned blog posts or get some hands-on experience by creating your own real-time GraphQL backend with Authentication, access control in around 30 minutes by following our Hasura backend tutorial at learn.hasura.io

Discussion

pic
Editor guide