How Authentication and Authorization Work for SPAs

Adding authentication to public clients such as Single Page Applications (SPA) and JavaScript applications can be a source of confusion. Identity Providers like Okta try to help you via multiple support systems. Still, it can feel like a lot of work. Especially since you’re responsible for way more than authentication alone in the applications you work on!

This is a companion discussion topic for the original entry at

I don’t understand from this how to validate the aud claim on the access token in my API.

e.g. I have an SPA served on

I have a JSON/HTTP API served on

I have configured my SPA to discover from - so it is hitting as a start point.

After successful authentication my SPA gets an access_token field containing "aud": "".

I pass that as Authorization: Bearer <access_token> when calling But how do I validate it server side? Do I have to make my server side app happy to accept as the aud? That seems wrong, surely it should be as the aud?

I can change the default Authorization Server in Settings → Security → API to have an Audience of - but that makes no difference to the aud claim returned in the access_token when doing the OIDC flow. I suspect because I am getting the metadata from* rather than*. Am I right in this?

I find it very frustrating that this is so opaque and obscure when getting an access token to use with an API must be the absolutely standard use case, and validating the aud claim of an oauth2 acces token is meant to be a critical security action?