# Unable to communicate between single page application and server

**URL:** <https://community.auth0.com/t/unable-to-communicate-between-single-page-application-and-server/141780>\
**Category:** Get Help\
**Tags:** apis, application\
**Created:** [August 26, 2024, 11:57am UTC](https://community.auth0.com/t/unable-to-communicate-between-single-page-application-and-server/141780 "2024-08-26T11:57:12Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![arshsharma461](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/arshsharma461/32/59415_2.png) [@arshsharma461](https://community.auth0.com/u/arshsharma461)\
**Post date:** [August 26, 2024, 11:57am UTC](https://community.auth0.com/t/unable-to-communicate-between-single-page-application-and-server/141780/1 "2024-08-26T11:57:12Z")

</div>

This is my current flow:

I have a single page application where the user logs in. When they log in I save their `accessToken`:

```auto
const accessToken = await auth0Client.getTokenSilently();

```

In the browser storage. Then I have a chrome extension which picks up the token from the browser storage. The exntesion needs to send a request to an API endpoint `/generate` (which I added in the API section of the auth0 app). The same server code is serving the SPA for login and the `/generate` API endpoint. But when I pass along with the authToken I received after logging in to the `/generate` endpoint it says that it’s invalid. If I use the token provided in the “Test” section, that works.

So I’m unable to understand why the token given by the SPA isn’t valid for authenticating with the API.

Here’s my `server.js`:

```js
const express = require("express");
const cors = require("cors");
const { join } = require("path");
const app = express();
const { auth, requiredScopes } = require("express-oauth2-jwt-bearer");

const checkJwt = auth({
  audience: "http://localhost",
  issuerBaseURL: "https://dev-csc8n75wcojtwxmv.us.auth0.com/",
  tokenSigningAlg: "RS256",
});

app.use(express.json());
app.use(cors());

// Serve static assets from the /public folder
app.use(express.static(join(__dirname, "public")));

// Endpoint to serve the configuration file
app.get("/auth_config.json", (req, res) => {
  res.sendFile(join(__dirname, "auth_config.json"));
});

// Serve the index page for all other requests
app.get("/*", (_, res) => {
  res.sendFile(join(__dirname, "index.html"));
});

app.post("/generate", checkJwt, async (req, res) => {
  const token =
    req.headers.authorization && req.headers.authorization.split(" ")[1];
  console.log(token);
  // get/validate user details from token
  const { prompt } = req.body;

 // app specific code
});

// Listen on port 3000
app.listen(3000, () => console.log("Application running on port 3000"));

```

my `app.js` code:

```js
let auth0Client = null;

const fetchAuthConfig = () => fetch("/auth_config.json");

const configureClient = async () => {
  const response = await fetchAuthConfig();
  const config = await response.json();

  auth0Client = await auth0.createAuth0Client({
    domain: config.domain,
    clientId: config.clientId,
  });
};

window.onload = async () => {
  await configureClient();
  updateUI();
  const isAuthenticated = await auth0Client.isAuthenticated();

  if (isAuthenticated) {
    // show gated content
    return;
  }

  const query = window.location.search;
  if (query.includes("code=") && query.includes("state=")) {
    await auth0Client.handleRedirectCallback();
    updateUI();
    window.history.replaceState({}, document.title, "/");
  }
};

const updateUI = async () => {
  const isAuthenticated = await auth0Client.isAuthenticated();

  document.getElementById("btn-logout").disabled = !isAuthenticated;
  document.getElementById("btn-login").disabled = isAuthenticated;

  if (isAuthenticated) {
    document.getElementById("gated-content").classList.remove("hidden");

    const accessToken = await auth0Client.getTokenSilently();

    document.getElementById("ipt-access-token").innerHTML = accessToken;
    const message = {
      type: "auth0_token",
      token: accessToken,
    };
    window.postMessage(message, "*");

    document.getElementById("ipt-user-profile").textContent = JSON.stringify(
      await auth0Client.getUser()
    );
  } else {
    document.getElementById("gated-content").classList.add("hidden");
  }
};

const login = async () => {
  await auth0Client.loginWithRedirect({
    authorizationParams: {
      redirect_uri: window.location.origin,
    },
  });
};

const logout = () => {
  auth0Client.logout({
    logoutParams: {
      returnTo: window.location.origin,
    },
  });
};

```

---

<div class="post-metadata">

**Author:** ![ty.frith](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/ty.frith/32/58484_2.png) [@ty.frith](https://community.auth0.com/u/ty.frith)\
**Post date:** [August 26, 2024, 8:51pm UTC](https://community.auth0.com/t/unable-to-communicate-between-single-page-application-and-server/141780/3 "2024-08-26T20:51:56Z")

</div>

Hey there @arshsharma461 welcome to the community!

I have a hunch this is due to the lack of an [audience](https://community.auth0.com/t/what-is-the-audience/71414) param in access tokens. You’ll want to add it in your `loginWithRedirect` method:

```auto
const login = async () => {
  await auth0Client.loginWithRedirect({
    authorizationParams: {
      redirect_uri: window.location.origin,
      audience: "https://your-api-identifier"
    },
  });
};

```

The api identifier being that of the API you’ve registered in your dashboard:

> **[Register APIs](https://auth0.com/docs/get-started/auth0-overview/set-up-apis)**
>
> Learn how to register APIs in the Auth0 Dashboard.

---

<div class="post-metadata">

**Author:** ![arshsharma461](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/arshsharma461/32/59415_2.png) [@arshsharma461](https://community.auth0.com/u/arshsharma461)\
**Post date:** [August 27, 2024, 6:17am UTC](https://community.auth0.com/t/unable-to-communicate-between-single-page-application-and-server/141780/4 "2024-08-27T06:17:20Z")

</div>

Thanks for the reply @ty.frith!

I implemented your suggestion: (in app.js)

```js
const login = async () => {
  await auth0Client.loginWithRedirect({
    authorizationParams: {
      redirect_uri: window.location.origin,
      audience: "http://localhost",
    },
  });
};

```

But I still see this error in my console:

```auto
Application running on port 3000
InvalidTokenError: Invalid Compact JWS
    at /Users/arsh/code/authdemo/node_modules/express-oauth2-jwt-bearer/dist/index.js:300:19
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async /Users/arsh/code/authdemo/node_modules/express-oauth2-jwt-bearer/dist/index.js:403:24

```

Any idea how I could fix/debug this?

---

<div class="post-metadata">

**Author:** ![arshsharma461](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/arshsharma461/32/59415_2.png) [@arshsharma461](https://community.auth0.com/u/arshsharma461)\
**Post date:** [August 27, 2024, 7:06am UTC](https://community.auth0.com/t/unable-to-communicate-between-single-page-application-and-server/141780/5 "2024-08-27T07:06:52Z")

</div>

After your suggesting I even tried adding the audience field in other places in app.js like:

```js
const configureClient = async () => {
  const response = await fetchAuthConfig();
  const config = await response.json();

  auth0Client = await auth0.createAuth0Client({
    domain: config.domain,
    clientId: config.clientId,
    audience: "http://localhost",
  });
};

```

and

```js
    const accessToken = await auth0Client.getTokenSilently({
      audience: "http://localhost",
    });

```

and

```js
const login = async () => {
  await auth0Client.loginWithRedirect({
    authorizationParams: {
      redirect_uri: window.location.origin,
      audience: "http://localhost",
    },
  });
};

```

But still it’s not working. My tenant id is `dev-csc8n75wcojtwxmv` in case you need to take a look. Thanks!

---

<div class="post-metadata">

**Author:** ![arshsharma461](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/arshsharma461/32/59415_2.png) [@arshsharma461](https://community.auth0.com/u/arshsharma461)\
**Post date:** [August 27, 2024, 7:28am UTC](https://community.auth0.com/t/unable-to-communicate-between-single-page-application-and-server/141780/6 "2024-08-27T07:28:53Z")

</div>

Anoher update:

I used the Authentication API Debugger extension and got a token from there after adding `http://localhost` to the Audience list. When I use this token it works.

This means the code we’re writing to pass the audience is not working correctly? For reference I’m importing auth0 using:

```html
    <script src="https://cdn.auth0.com/js/auth0-spa-js/2.0/auth0-spa-js.production.js"></script>

```

in the `index.htm` which the server serves. I made the code changes you suggested, did `npm run dev`, logged out from the webpage, logged in to get a new access token which should have the audience field set, and then make the request which fails.

When I decode the token I get using ([https://jwt.io/](https://jwt.io/)) I see this:

 ![Screenshot 2024-08-27 at 12.56.55 PM](https://global.discourse-cdn.com/auth0/original/3X/0/a/0a3c541f4cb81b7d1069b59b8f9417abd24904d3.png)

This proves the token isn’t of the correct type but I’m not sure why that’s happening, can you please help out?

---

<div class="post-metadata">

**Author:** ![ty.frith](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/ty.frith/32/58484_2.png) [@ty.frith](https://community.auth0.com/u/ty.frith)\
**Post date:** [August 27, 2024, 9:59pm UTC](https://community.auth0.com/t/unable-to-communicate-between-single-page-application-and-server/141780/7 "2024-08-27T21:59:33Z")

</div>

Hey there @arshsharma461 thanks for the additional details, and happy to help!

> [@arshsharma461](#):
>
> This proves the token isn’t of the correct type but I’m not sure why that’s happening, can you please help out?

It looks like you are still receiving an [opaque token](https://auth0.com/docs/secure/tokens/access-tokens#opaque-access-tokens) 🤔 Perhaps the use of `http://localhost` as an API identifier is giving you issues. Can you try registering a new API in your dashboard and using something like `https://test-api-endpoint` instead?

---

<div class="post-metadata">

**Author:** ![arshsharma461](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/arshsharma461/32/59415_2.png) [@arshsharma461](https://community.auth0.com/u/arshsharma461)\
**Post date:** [August 28, 2024, 6:59am UTC](https://community.auth0.com/t/unable-to-communicate-between-single-page-application-and-server/141780/8 "2024-08-28T06:59:18Z")

</div>

Thanks! Just tried it and even that isn’t working, in `app.js`:

```js
const updateUI = async () => {
  const isAuthenticated = await auth0Client.isAuthenticated();

  document.getElementById("btn-logout").disabled = !isAuthenticated;
  document.getElementById("btn-login").disabled = isAuthenticated;

  if (isAuthenticated) {
    document.getElementById("gated-content").classList.remove("hidden");

    const accessToken = await auth0Client.getTokenSilently({
      audience: "https://textella-api-endpoint",
    });

    document.getElementById("ipt-access-token").innerHTML = accessToken;
    const message = {
      type: "auth0_token",
      token: accessToken,
    };
    window.postMessage(message, "*");

    document.getElementById("ipt-user-profile").textContent = JSON.stringify(
      await auth0Client.getUser()
    );
  } else {
    document.getElementById("gated-content").classList.add("hidden");
  }
};

```

and

```js
const login = async () => {
  await auth0Client.loginWithRedirect({
    authorizationParams: {
      redirect_uri: window.location.origin,
      audience: "https://textella-api-endpoint",
    },
  });
};

```

---

<div class="post-metadata">

**Author:** ![arshsharma461](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/arshsharma461/32/59415_2.png) [@arshsharma461](https://community.auth0.com/u/arshsharma461)\
**Post date:** [August 28, 2024, 7:15am UTC](https://community.auth0.com/t/unable-to-communicate-between-single-page-application-and-server/141780/9 "2024-08-28T07:15:08Z")

</div>

Hey! I managed to finally get it working. I think what did the trick was specifying `audience` under `authorizationParams` instead of directly like earlier. It was needed only in the `updateUI()` function and not the `login` one.

What worked:

```js
const updateUI = async () => {
// code

    const accessToken = await auth0Client.getTokenSilently({
      authorizationParams: {
        audience: "https://textella-api-endpoint",
      },
    });

// code
};

```

what wasn’t working earlier:

```auto
const updateUI = async () => {
// code

    const accessToken = await auth0Client.getTokenSilently({
        audience: "https://textella-api-endpoint",
    });

// code

```

Thanks for all the support!

---

<div class="post-metadata">

**Author:** ![arshsharma461](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/arshsharma461/32/59415_2.png) [@arshsharma461](https://community.auth0.com/u/arshsharma461)\
**Post date:** [August 28, 2024, 7:17am UTC](https://community.auth0.com/t/unable-to-communicate-between-single-page-application-and-server/141780/10 "2024-08-28T07:17:52Z")

</div>

I had a follow up question, if you can help with that please. How do I get user details once I do have this validated token in my `server.js`:

```js
const checkJwt = auth({
  audience: "https://textella-api-endpoint",
  issuerBaseURL: "https://dev-csc8n75wcojtwxmv.us.auth0.com/",
  tokenSigningAlg: "RS256",
});

app.post("/generate", checkJwt, async (req, res) => {
  const token =
    req.headers.authorization && req.headers.authorization.split(" ")[1];
  console.log(token);
  // get/validate user details from token
  // app code
});

```

In the api endpoint for `/generate` I want to get the details of the user that just got validated, how do I do that?

Thanks!

---

<div class="post-metadata">

**Author:** ![arshsharma461](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/arshsharma461/32/59415_2.png) [@arshsharma461](https://community.auth0.com/u/arshsharma461)\
**Post date:** [August 29, 2024, 5:56am UTC](https://community.auth0.com/t/unable-to-communicate-between-single-page-application-and-server/141780/11 "2024-08-29T05:56:31Z")

</div>

Hey @ty.frith! I just noticed that the code I had is causing a weird bug. Ever since I did this in `app.js`:

```js
if (isAuthenticated) {
    document.getElementById("gated-content").classList.remove("hidden");

    const accessToken = await auth0Client.getTokenSilently({
      authorizationParams: {
        audience: "https://textella-api-endpoint",
      },
    });

    document.getElementById("ipt-access-token").innerHTML = accessToken;
    const message = {
      type: "auth0_token",
      token: accessToken,
    };
    window.postMessage(message, "*");

    document.getElementById("ipt-user-profile").textContent = JSON.stringify(
      await auth0Client.getUser()
    );
  } 

```

When I log in from a different user, it’s not able to get the the `authToken` and display anything in the HTML. But when I remove ` audience: "https://textella-api-endpoint",` everything works as it did in the sample SPA JavaScript app. Any idea what might be causing this?

The error I get in my console is: `Error: Consent required`

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/auth0/original/3X/b/5/b560f266932fcce5d57f09a6595bd50518cae3f3.jpeg) [@system](https://community.auth0.com/u/system)\
**Post date:** [September 12, 2024, 5:57am UTC](https://community.auth0.com/t/unable-to-communicate-between-single-page-application-and-server/141780/12 "2024-09-12T05:57:06Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
