In this blog post we are going to use Firebase Authentication with Hasura. There are several tutorials about using these two together but we are going to make use of an upcoming Hasura feature called JWT claims customization. This feature allows mapping existing JWT claims to Hasura session variables so you can use authentication services out of the box without adjusting custom claims. This is especially useful in case your auth provider doesn't allow setting custom claims like Azure AD. Here we are going to see how can we use this feature with Firebase Auth to speed up the process by eliminating the need to set custom claims via Firebase Admin SDK.

Creating a Firebase Project

  1. Create a new Firebase project from the Firebase console.
  2. Enable Email/Password authentication from Authentication > Sign-in method.

Deploying Hasura Engine on Docker

By the time writing this post, this feature hasn't been released yet. For the time being we are going to use a specific image to test it out but it will be soon available with the next Hasura release.
Make sure you have installed Docker on your computer.

Create a docker-compose.yaml and past the following code.

version: '3.6'
services:
  postgres:
    image: postgres:12
    restart: always
    volumes:
    - db_data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: postgrespassword
  graphql-engine:
    image: hasura/graphql-engine:pull3575-5762ee68
    ports:
    - "8080:8080"
    depends_on:
    - "postgres"
    restart: always
    environment:
      HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/postgres
      HASURA_GRAPHQL_ENABLE_CONSOLE: "true" 
      HASURA_GRAPHQL_ADMIN_SECRET: password
      HASURA_GRAPHQL_JWT_SECRET: '{"jwk_url": "https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com", "audience": "<project-id>", "issuer": "https://securetoken.google.com/<project-id>", "claims_map": {"x-hasura-allowed-roles": ["user"],"x-hasura-default-role": "user","x-hasura-user-id": {"path":"$$.user_id"}}}'
volumes:
  db_data:
docker-compose.yaml.

The important part here is the HASURA_GRAPHQL_JWT_SECRET environment variable. Here we are adding the required configuration for Firebase Auth. Remember to change <project-id> with your Firebase project id in audience and issuer.

We are also using the new JWT claims customization feature my mapping existing claims to Hasura sessions variables. Lets have a look at the decoded version of Firebase token in jwt.io

{
  "name": "Can Taşpınar",
  "iss": "https://securetoken.google.com/<project-id>",
  "aud": "<project-id>",
  "auth_time": 1598040546,
  "user_id": "sOsMsWKoEyTzsgITkZNQVCa2wvg2",
  "sub": "sOsMsWKoEyTzsgITkZNQVCa2wvg2",
  "iat": 1600345172,
  "exp": 1600348772,
  "email": "can@cantaspinar.com",
  "email_verified": false,
  "firebase": {
    "identities": {
      "email": [
        "can@cantaspinar.com"
      ]
    },
    "sign_in_provider": "password"
  }
}

This is the payload section of the Firebase token and we can see the user_id is stored at the root level. We can now tell Hasura to look for the user_id in the Firebase token and map it to x-hasura-user-id session variable. We are going to hard-code the user role but it is also possible to specify a path for that too.

"claims_map": {"x-hasura-allowed-roles": ["user"],"x-hasura-default-role": "user","x-hasura-user-id": {"path":"$$.user_id"}}

Run Hasura GraphQL engine & Postgres with the following command.

docker-compose up -d

That is all you need to do. You can now set your permissions in Hasura console and use Firebase authentication out of the box without making further configuration.