hasura / graphql-engine

Blazing fast, instant realtime GraphQL APIs on your DB with fine grained access control, also trigger webhooks on database events.
https://hasura.io
Apache License 2.0
31.16k stars 2.76k forks source link

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

Open awconway opened 4 years ago

awconway commented 4 years ago

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 commented 4 years ago

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)
tirumaraiselvan commented 4 years ago

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

awconway commented 4 years ago

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.

tirumaraiselvan commented 4 years ago

@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

awconway commented 4 years ago

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

nahueld-owners commented 2 years ago

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

barbalex commented 1 year ago

I am getting this when users do not log in and thus no token exists