Authorization Bearer Token Using GraphQL in Next.js App

Hi Sebastian,

I’m about to deploy my app live and I’m currently configuring my client under Settings → Security → Clients and I was wondering how I should handle the situation when the token expires?

I’m in particular referring to the following text in the “Connect” dialog:

Tokens usally expire after 30days, but you can request multiple tokens.

If I enable “Allow anonymous access.” for my client everything will obviously work but I want to be able to secure this client as much as possible.

Can you please advice how I can go about it?

Btw, the following is how I’m currently using the GraphQL endpoint in my Next.js app:

export async function fetchAllProductsTotal(): Promise<number> {
  try {
    const response = await fetch(`${process.env.GRAPHQL_ENDPOINT}`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        query: queryAllProductsTotal,
      }),
    });

    if (!response.ok) {
      throw new Error(
        `Failed to fetch all products total from Squidex. Status: ${response.status} ${response.statusText}`,
      );
    }

    const result = await response.json();

    if (!result.data || !result.data.queryProductContentsWithTotal) {
      console.error("No total products data found in Squidex.");
      return 0;
    }

    return result.data.queryProductContentsWithTotal.total;
  } catch (error) {
    console.error(error);
    return 0;
  }
}

I could add the Authorization: Bearer header to my POST request but it would still fail after 30 days?

You could just use the node SDK? GitHub - Squidex/sdk-node: Node.js SDK for the Squidex API

If this is not possible, I would implement the following logic:

  1. Implement a general middleware or fetch function
  2. If there is no token in the cache, fetch the token first, then make the actual request.
  3. Store the token in the cache usign the lifetime of the response object.
  4. If the actual request fails, get a new token and try again.

Thanks for the quick reply.

I looked at the SDK and it looks like something that would probably work but I would have to rewrite tons of code and the testing that comes with that so today this is not an option. Maybe in the future. Also I noticed the SDK is still in RC?

Regarding the second option:

  1. Implement a general middleware or fetch function ← Next.js has some middleware stuff in it that you could probably use. But this sounds like the most complicated approach? A generic fetch function might work.

  2. If there is no token in the cache, fetch the token first, then make the actual request. ← what do you mean by “fetch the token first”? The first thing that comes to mind is the “Get a token using curl” in Client section in Squidex:

$ curl
-X POST 'https://cloud.squidex.io/identity-server/connect/token'
-H 'Content-Type: application/x-www-form-urlencoded'
-d 'grant_type=client_credentials&
client_id=xyz:default
client_secret=blah
scope=squidex-api'

is this what you are referring to?

Update 1: Now that I come to think of it; wouldn’t it be easier if the token is generated once, with no expiration, and then, if needed, one could manually generate a new token. This is how most systems that use some sort of secret key/sensitive credentials work today. I think that in the end the responsibility is on the developer and not the system whether or not the secret is handled appropriately. So I guees what I’m trying to say is that I think that the bearer token for a squidex client should not expire and if you need a new one for some reason you should be able to manually generate a new one from within the squidex UI (like other SaaS dashboards do it). Oh, and one last thing. There is usually a “dev API secrets/keys” and a “prod API secrets/keys” in these systems so that it becomes really obvious which to use and when.

Sebastian, do you think this would be a major thing? Hard to implement? A lot of rework in the UI etc I’d imagine?