How to call a secured AWS API Gateway resource from a static web page?

I have deployed an API Gateway and secured it with Auth0 successfully. I can verify this from CLI using curl.

For example:

$ curl -X POST --header "Authorization:Bearer ey...3w" https://abcdefg.execute-api.ap-southeast-2.amazonaws.com/demo | jq .
{
  "message": "Hello Demo"
}

$ curl -X POST https://abcdefg.execute-api.ap-southeast-2.amazonaws.com/demo | jq .
{
  "message": "Unauthorized"
}

I also have a static web page created using the jQuery guide and deployed it into a static S3 website. I can successfully login to the SPA page using Auth0.

However, after that, I don’t know how to acquire a JWT token to include it in my AJAX calls’ Authorization headers to invoke my API from my web page.

In other words, what do I have to put in the // TODO: Call https://abcdefg.execute-api.ap-southeast-2.amazonaws.com/demo section in the following block of code, which is copied from https://auth0.com/docs/quickstart/spa/jquery/01-login and modified a bit:

  function displayButtons() {
    if (isAuthenticated()) {
      loginBtn.css('display', 'none');
      logoutBtn.css('display', 'inline-block');
      loginStatus.text('You are logged in!');

      // TODO: Call https://abcdefg.execute-api.ap-southeast-2.amazonaws.com/demo
    } else {
      loginBtn.css('display', 'inline-block');
      logoutBtn.css('display', 'none');
      loginStatus.text('You are not logged in! Please log in to continue.');
    }
  }

I can’t use the access_token stored in the local storage as it is not a valid JWT token. If I pass:

headers: {
    "Authorization": `Bearer ${localStorage.getItem('access_token')}`
}

The authorizer function fails with this error:

TypeError: Cannot read property 'header' of null

At this line:

var kid = decoded.header.kid;

Because decoded’s value will be computed as null:

var decoded = jwt.decode(token, { complete: true });

What am I missing here?

Thanks in advance.

Resolved. According to the docs:

  • If the audience is set to turingg.auth0.com/userinfo, then the Access Token will be an opaque string.

  • If the audience is set to the unique identifier of a custom API, then the Access Token will be a JSON Web Token (JWT).

So I had to change

var webAuth = new auth0.WebAuth({
  domain: AUTH0_DOMAIN,
  clientID: AUTH0_CLIENT_ID,
  redirectUri: AUTH0_CALLBACK_URL,
  audience: 'https://' + AUTH0_DOMAIN + '/userinfo',
  responseType: 'code token id_token',
  scope: 'openid profile email',
  leeway: 60
});

to

var webAuth = new auth0.WebAuth({
  domain: AUTH0_DOMAIN,
  clientID: AUTH0_CLIENT_ID,
  redirectUri: AUTH0_CALLBACK_URL,
  audience: '<unique identifier for my api>',
  responseType: 'code token id_token',
  scope: 'openid profile email',
  leeway: 60
});