scrawny-salmonS
Refine14mo ago
6 replies
scrawny-salmon

Graphql token

I'm trying to use graphql (using urql) as my data provider and all was ok until I had to authenticate my requests. I need to use send a token (stored either in cookies or localstorage) in the headers but can't seem to make it work.

My issue is that, even though the data provider setup is done in a "use client" file, this thing is rendered on the server first, and even though the queries happen on the client side it seems like the initial setup for the urql provider is done in the server.

In the authExchange part of my gqlClient setup I even added something like this:
      if (typeof localStorage !== 'undefined') {
        token = await localStorage.getItem('token');
        console.log('SETTING TOKEN', token);
      }


And I do see this console.log happening on the browser but the request never sends the header to the server.

Here's my config for the gqlClient that is being used by Refine:

'use client';

// ... imports redacted

const gqlClient = new Client({
  url: API_URL,
  exchanges: [
    fetchExchange,
    authExchange(async (utils) => {
      let token: null | string = null;

      if (typeof localStorage !== 'undefined') {
        token = await localStorage.getItem('token');
        console.log('SETTING TOKEN', token);
      }

      return {
        addAuthToOperation(operation) {
          if (!token) return operation;

          return utils.appendHeaders(operation, {
            authorization: `Bearer ${token}`,
          });
        },
        didAuthError(error) {
          return error.graphQLErrors.some((e) => e.message === 'Unauthorized');
        },
        async refreshAuth() {},
      };
    }),
  ],
});

function convertOperationName(resource: string): string {
  return `admin${camelCase(resource, { pascalCase: true })}`;
}

export const dataProvider = createDataProvider(gqlClient);
Was this page helpful?