graphql-engine icon indicating copy to clipboard operation
graphql-engine copied to clipboard

apollo client queries JWT error (CompactDecodeError Invalid number of parts: Expected 3 parts; got 1)

Open awconway opened this issue 3 years ago • 6 comments

I have set up a gatsby site with auth0 following the hasura community sample app gatsby-contentful-auth0, but am getting an error with the JWT:

Error: GraphQL error: Could not verify JWT: JWSError (CompactDecodeError Invalid number of parts: Expected 3 parts; got 1)

I have gone through all the steps in the tutorial provided by hasura here. So for example, if I insert the JWT Bearer token generated from a sample as per these instructions the queries in the site work. But when trying to get the token from the client it isn't working.

const createApolloClient = authToken => {
  return new ApolloClient({
    link: new HttpLink({
      uri: "https://honest-longhorn-93.hasura.app/v1/graphql",
      headers: {
        Authorization: `Bearer ${authToken}`, //triggers error: GraphQL error: Could not verify JWT: JWSError (CompactDecodeError Invalid number of parts: Expected 3 parts; got 1)
// Authorization: `Bearer <sample auth0 token for testing>}` //**queries work in the app when a sample token is used**
 // 'X-Hasura-Admin-Secret': 'myadminsecretkey' //**this works too**

      },
    }),
    cache: new InMemoryCache(),
  })
}

My database is on Hasura Cloud where I have the HASURA_GRAPHQL_JWT_SECRET stored. There is no issue with auth0 as new users are getting written to the hasura cloud database.

Any advice would be greatly appreciated.

Thanks.

awconway avatar Aug 26 '20 16:08 awconway

The problem here it seems was that the input to the createApolloClient function was passing in the payload of the token - not the actual token. So I added in a new function to auth.js

export const getToken = () => {
  return tokens.idToken
}

and used the snippet below in account.js instead so that the token would be passed to the headers argument of createApolloClient.

  const user = getProfile()
  const idToken = getToken()
  const client = createApolloClient(idToken)

awconway avatar Aug 28 '20 17:08 awconway

@awconway It seems you figured out the issue, can we close this?

tirumaraiselvan avatar Sep 01 '20 03:09 tirumaraiselvan

I think it would be good to check that the solution works in the community sample app (gatsby-contentful-auth0) and update it for others to use if it does. But from my perspective, it seems to work.

awconway avatar Sep 01 '20 14:09 awconway

@awconway The community sample app (gatsby-contentful-auth0) passes in the idToken to the createApolloClient function: https://github.com/hasura/graphql-engine/blob/f9aca45706f6dc56494e030bc2f2cabf2cdd1bb6/community/sample-apps/gatsby-contentful-auth0/app/src/pages/account.js#L35

tirumaraiselvan avatar Sep 07 '20 05:09 tirumaraiselvan

Yes I think it was meant to but it doesn't actually do it. As the community sample app (gatsby-contentful-auth0) is currently set up, user.idToken is empty. It doesn't work because user is created from the payload (see below) and the actual idToken needed for createApolloClient doesn't exist in the payload. At least for my app it didn't (but again - I have auth0 set up in the exact same way though so I suspect this is a problem with the community sample app too).

https://github.com/hasura/graphql-engine/blob/f9aca45706f6dc56494e030bc2f2cabf2cdd1bb6/community/sample-apps/gatsby-contentful-auth0/app/src/utils/auth.js#L56-L57

awconway avatar Sep 07 '20 12:09 awconway

This is also happening to me strangely only when the request is initiated from a mobile browser only... any help here? I don't think the client has anything to do, I have double checked and we are sending the right payload

nahueld-owners avatar Sep 16 '22 21:09 nahueld-owners