Authenticated Queries with GraphQL (Apolloclient)

Hello everbody,

It’s been hours and hours and I am still stucked, so I hope someone can help me.

I am using :
Backend : Strapi 4.1.11
Frontend : Nextjs (Apolloclient for graphQL)

I log in on the frontend, on store the jwt on a cookie :

          .setHeader('Set-Cookie', [
            cookie.serialize('token', jwt, {
              httpOnly: true,
              secure: process.env.NODE_ENV !== 'development',
              maxAge: 60 * 60 * 24 * 7, // 1 week
              sameSite: 'strict',
              path: '/',
            cookie.serialize('userid', id, {
              httpOnly: true,
              secure: process.env.NODE_ENV !== 'development',
              maxAge: 60 * 60 * 24 * 7, // 1 week
              sameSite: 'strict',
              path: '/',
          .json({ message:, jwt });

But because it’s httpOnly (for security reasons), how do I pass the token for every request ? As mentioned in the Strapi’s Docs :

Then on each request, send along an Authorization header in the form of { "Authorization": "Bearer YOUR_JWT_GOES_HERE" }. This can be set in the HTTP Headers section of your GraphQL Playground.

I followed ApolloClient doc, by setting a context with the headers inside (but this doesn’t work, because the httpOnly cookie is not accessible from client side) :

const httpLink = new HttpLink({
  uri: process.env.NODE_ENV === 'development' ? endpoint : prodEndpoint,
  credentials: 'include',

function createApolloClient(token = null) {
  const authLink = setContext((_, { headers }) => {
    const newHeaders = {
      headers: {
        ...(!!token && { authorization: `Bearer ${token}` }),
    return newHeaders;

  return new ApolloClient({
    ssrMode: typeof window === 'undefined', // set to true for SSR
    link: from([errorLink, authLink.concat(httpLink)]),
    cache: new InMemoryCache(),

It would be much appreciated if someone had a solution.


I also add that authentification works on the /graphql playground (by adding headers manually).

And as well, if I enter manually the token in the ApolloClient, it works.

Previously I was using the CMS Keystone 6, and the login operation was enough to make authenticated queries and mutations. I don’t understand why with Strapi I can’t do that so far.

u could try to restore the jwt in local storage , and access it when available by this example

authorization: localStorage.getItem(“token”) !== null && 'Bearer '+ localStorage.getItem(“token”) || “”

But from what I understood, client side cookies or Local Storage is not viable solution for security purposes.

One of many articles that talk about it :

1 Like

At the end, I found a solution, but it requires NextAuth, which is not ideal in my case, but it works.

Basically, you install NextAuth. And with it, you can get the jwt on Client Side with getSession();

oh wow bro thanks for the information and ur advice, i just know it. But, is that jwt from strapi store sensitive data? , in my case, with local storage when i console.log user, its only found id and exp, i dunno its sensitive or not

It is sensitive, because with it, you can make authenticated request.

1 Like