Fun with Auth0, React and tokens

I am working on a React-based Single-Page App (SPA) using Auth0 for authentication. For a while, I have been maintaining my own little helper library to do this. It uses the auth0/auth0-js library (which is described as “Client Side JavaScript toolkit for Auth0 API”) under the hood.

I’ve been aware of a new-ish recommended way to work with Auth0 for a while, and finally decided to migrate my sloppy integration over. I first started with auth0/auth0-spa-js, but soon realized that Auth0 maintains a React SDK, which uses auth0-spa-js under the hood, so I went with auth0/auth0-react instead.

Most of the steps are pretty straightforward as documented in this quick start guide. The part I struggled with the most was getting the Access Token to call a backend API.

Before, in my sloppy integration, I was using the ID token returned from the OAuth flow to call my backend API. It is actually a bad/ wrong implementation, as called out by Auth0 tokens documentation:

Do not use ID tokens to gain access to an API.

So in order to get a proper access token, I have the following code in the App.jsx component.

import React, { useState, useEffect } from 'react';
			import { useAuth0 } from '@auth0/auth0-react';
			function App() {
			  const [token, setToken] = useState();
			  const { getAccessTokenSilently } = useAuth0();
			  useEffect(() => {
			    (async () => {
			      const accessToken = await getAccessTokenSilently();

However, I could not understand why the accessToken I received was not in JWT format, but a small string of maybe 15 characters. It wasn’t a Bearer token I could use to make XHR call against the REST API server.

The Auth0 doc page on Access Tokens mentions 2 different kinds – “opaque” and “JWT”, but it didn’t mention how to get the JWT token. I was guessing that the small token I got back was the opaque token.

Not able to find any reference to this issue online, I randomly tried adding the audience to the call to get the token, which turned out to be exactly the missing piece for me.

  const token = await getAccessTokensSilently({
			    audience: ''

In hindsight, I’m guessing I was getting the opaque token because by default, Auth0 was returning the access token needed for the /userinfo endpoint only. If anyone knows the answer to this, I would love to know.

UPDATE: This behavior is documented in this post

In order to receive a JWT you must include an audience parameter with your token request.

“Between the World and Me” – Ta-Nehisi Coates

I’ve been wanting to read this book for a long time, and finally found the time to do so at the end of 2020. Wow! What an insightful read! I’m glad I got to experience it.

Based on reviews and comments about this popular book, one might go into reading it expecting an intellectual conversation about the history of race and racism in America. I was however enthralled by an intensely emotional and honest telling of a personal narrative. Even though the story is of an individual, I couldn’t help but think about the countless human stories similar to this one, having been lived and is being lived out every day, some perhaps more tragic. I also found myself comparing the story with how I grew up and found my ways in the world, and how different my experiences and thus perspective are. Yet there is a common humanity in the personal struggles and the human emotions that I could relate to and recognize. That is the lesson I took away from the book – while the conversation about race and racism is often explored through the lens of rationality and morality, it is first and foremost a lived experience, and one filled with intense and personal feelings and memories.

Values-based grouping

I just watched this TED talk about the end of globalization and where it goes from here.

I don’t fully agree with it – some of the statements are generalizing and simplistic. However, it raised some interesting thoughts.

For the last few decades, globalization has seen a blurring of borders, many times based on geographical proximity. Some examples I could immediately think of include the European Union, North America (in the context of NAFTA), ASEAN etc. There are probably many other, though I’m not as familiar.

What if in the future, we see more blocs coming together of alliances based on value systems instead of geographical attributes? Systems that would include economic policies, population size, diplomatic outlook, technology, human rights advocacy or abuse etc. Are there examples of such grouping already in existence?

Firestore backup with GitHub Actions

I needed a way to perform automated backup for my GCP Firestore database. I found out that Firestore has Import/ Export functionality, and it seems to be the recommended way to do backup. So I created a simple GitHub Actions workflow to do this:

name: Firestore backup
			    - cron: "0 19 * * *"
			    runs-on: ubuntu-latest
			      - uses: GoogleCloudPlatform/github-actions/[email protected]
			          service_account_email: '<service-account-name>@<project-id>'
			          service_account_key: ${{ secrets.SA_KEY }}
			          project_id: '<project-id>'
			      - name: Backup
			        run: |-
			          gcloud components install beta
			          gcloud beta firestore export gs://<storage-bucket-id>

This workflow can be triggered in 2 ways, manually (due to workflow_dispatch trigger), or on a schedule (cron syntax).

The first step set up and authenticate the gcloud cli. The second step triggers to export action on GCP.
Currently firestore export is only available on gcloud beta, so an installation step of the beta component is needed.

The cloud storage bucket would need to be created beforehand. I created mine with the NEARLINE storage class to save on some cost.