I have created 3 major applications with Auth0 and still don't get the hang of it

So I did it again… I created a webapp as SPA, coded an Backend + API and spiced it up with some fancy UI. To quickly get going the API does not require auth or user scope in the beginning, but as features get more complex this becomes a necessity.

If I remember one thing from my short time in ITsec, it is: “don’t roll your own crypto” and I would even extend that to “don’t roll your own auth”. Hence the reason I choose Auth0. My requirements are far from special, so it should be easy to get started.

Creating an application is easy and if opting for universal login, there is not much further setup required. Setting the correct callback and redirect urls is “challenging” for the first time, but peanuts compared to what comes after.

So here I am. Freshly created webapp with Auth0 powered authentication.

I honestly thought that’s it and started to write code for verifying JWT tokens in the API. The first library I tried: “jwt malformed” … ok it was last updated 5 years ago, probably something changed in crypto. Next library (officially auth0): “jwt malformed” Hmm, that’s weird. Is there something wrong with my token?

Spinning up jwt.io and checking the token: “signature invalid” Hmm, wird. What next followed was a deep dive running through the auth0 settings and docs and 3hours flew away in no time.

Some open questions remain:

  • Why is JWT token invalid on jwt.io?
  • Why can’t I validate my jwt token although everything else seems to be just fine.
  • why do I have to consent my own (first party) application if I explicitly set an audience and allow to skip the user consent
  • why is adding information to jwt payload becoming further complicated with rules and then flows?
  • Why do I have to dig down the auth0 rabbit hole again and again for seemingly “standard” things?

I believe consent is mandatory if localhost is one of the URLs configured on allowed callbacks.

I would guess that the jwt is using a different encryption algorithm than the one you selected in jwt.io

Thanks. Removing localhost from callbacks did the trick. From there I was able to provide an audience, which populated my JWT payload, which made it verifyable.