nuxt-graphql-client icon indicating copy to clipboard operation
nuxt-graphql-client copied to clipboard

Access token & refresh token setup

Open TitusKirch opened this issue 3 years ago • 15 comments

I just found the project here and read #3. Now I have the following question/feature request:

Will the implementation of an access token and a refresh token setup be supported in the future? E.g. if an error message "token expired" comes back, you automatically call a defined query to generate a new access token with its refresh token (HTTP cookie) and then the original query is automatically executed again.

TitusKirch avatar Mar 12 '22 19:03 TitusKirch

Will the implementation of an access token and a refresh token setup be supported in the future

@TitusKirch Yes, support for access & refresh tokens are already in the pipeline.

if an error message "token expired" comes back, you automatically call a defined query to generate a new access token with its refresh token (HTTP cookie) and then the original query is automatically executed again

Our implementation doesn't yet address this as, though it's a great feature and one that I'll definitely be adding to this module. Built-in support for different authentication error cases would greatly improve DX and make the module easier to adapt for newer developers.

@TitusKirch Thank you for the feedback!

Diizzayy avatar Mar 12 '22 21:03 Diizzayy

@Diizzayy Thanks for the quick reply! That sounds fanatastic, I'm curious about the future. Good luck in advance.

TitusKirch avatar Mar 13 '22 13:03 TitusKirch

@Diizzayy Speaking about authentication, how do you set custom headers on the server side if you want to authentication to the graphql endpoint? We need this 'how to' example in the docs. Thanks.

dodanex avatar Mar 18 '22 21:03 dodanex

@dodanex Proper documentation is right around the corner.

For setting authentication header

useGqlToken("my_token")

Using the function above, the header authorization: Bearer my_token would be added to all subsequent requests.

  • Set headers for default client
useGqlHeaders({ 'X-Custom-Header': 'Custom Value' })
  • Set headers for a specific client (multi-client mode)
useGqlHeaders({
  'X-Custom-Header': 'Custom Value'
}, 'my-client')

calling either useGqlToken or useGqlHeaders would apply the needed headers to all requests called afterwards.

Diizzayy avatar Mar 18 '22 21:03 Diizzayy

@Diizzayy great job. Thanks

dodanex avatar Mar 18 '22 21:03 dodanex

@dodanex Looking forward to hearing your feedback while we continue perfecting the module.

Diizzayy avatar Mar 18 '22 22:03 Diizzayy

So I cannot start Nuxt because Failed to load schema for "gql-sdk.ts", I suspect it fails because no authentication token header is there. I have added the useGqlHeaders in my app.vue, however that is of course after starting nuxt...

Any way I can add the header before trying to load the schema?

larswww avatar Mar 21 '22 15:03 larswww

@larswww you can add the key GQL_TOKEN to your .env to add the auth header added

Diizzayy avatar Mar 21 '22 16:03 Diizzayy

Shopify Storefront API requires a custom header name for their auth token.

larswww avatar Mar 23 '22 14:03 larswww

@larswww In prior versions, a custom auth header could only be set within the app ( not at build nor nuxi dev ) as seen below:

<script lang="ts" setup>
useGqlToken('secret_token', { config: { name: 'X-CUSTOM-HEADER' } })

const { data } = await useAsyncData('starlink', () => GqlLaunches())
</script>

In the latest version that I just released (nuxt-graphql-client v0.0.9), you can set the auth custom header as seen below

export default defineNuxtConfig({
  modules: ['nuxt-graphql-client'],

  publicRuntimeConfig: {
    'graphql-client': {
      clients: {
        default: {
          host: 'https://api.github.com/graphql', // process.env.GQL_HOST overrides this value
          token: {
            name: 'X-CUSTOM-AUTH' // process.env.GQL_TOKEN_NAME overrides this value
          }
        }
      }
    }
  }
})

if you're using a single client, you can also set GQL_TOKEN_NAME in your .env. When using a single client you can omit having to configure publicRuntimeConfig at all, and just using use .env as seen below:

GQL_HOST="https://api.github.com/graphql"
GQL_TOKEN="YOUR_GITHUB_TOKEN"

Diizzayy avatar Mar 23 '22 20:03 Diizzayy

Any update of this issue ? Provide a middleware who catch error globally will be really nice 😀

aspitrine avatar May 16 '22 12:05 aspitrine

Yes, support for access & refresh tokens are already in the pipeline.

Sounds good. Can't wait for it!

ghost avatar Jun 29 '22 12:06 ghost

Hey @Diizzayy, great work on this one! Just having few questions.

Where is the token saved? Would usage of useGqlToken with empty string reset it?

Where is the token saved? Would usage of useGqlToken with empty string reset it? ( thinking of saving it in a cookie and refreshing it if its lost after a session)

Also would love if an enhancement can be added and the capitalized first letter can be optional when making requests

georgiai1 avatar Aug 23 '22 22:08 georgiai1

@gkkirilov I replied from my phone and edited your comment by mistake

Would usage of useGqlToken with empty string reset it? ( thinking of saving it in a cookie and refreshing it if its lost after a session)

@gkkirilov The token is saved in memory, hence you do need to handle the storage and retrieval manually ( currently considering if it's worth integrating the token storage functionality ).

As for your question, Yes, passing either null or an empty string should in fact reset the auth header.

Diizzayy avatar Aug 23 '22 22:08 Diizzayy

It's possible to get a retry method inside the error in useGqlError ?

My use case is :

  • I made a request
  • Failed, need refresh token
  • useGqlError call
  • I refresh my token + useGqlToken to put the new token
  • Recall the initial request

Thanks in advance

aspitrine avatar Sep 15 '22 14:09 aspitrine

This functionality has been possible for quite some time now via the useGqlError utility

/nuxt-app/plugins/gql-error.ts

export default defineNuxtPlugin(() => {
  useGqlError((err) => {
    const tokenExpired = err.gqlErrors.some(err => err?.message.includes('<token_expiration>'))

    if (tokenExpired) {
      // Handle token expiration
    }
  })
})

Diizzayy avatar Nov 25 '22 17:11 Diizzayy

As far as I'm aware, useGqlError doesn't retry the request or provide a way to do so in the function itself.

A way to implement this could be to return a value in the error hook that tells the client to retry the query.

BlakeB415 avatar Dec 03 '22 19:12 BlakeB415

It's possible to get a retry method inside the error in useGqlError ?

My use case is :

  • I made a request
  • Failed, need refresh token
  • useGqlError call
  • I refresh my token + useGqlToken to put the new token
  • Recall the initial request

Thanks in advance

This functionality has been possible for quite some time now via the useGqlError utility

@Diizzayy Before I open a new issue on this, is this really possible at the moment and is the documentation simply missing? I have now tried something, but have not come to a solution. How to say at "// Handle token expiration" after the token has been freshed that the query has been executed again?

TitusKirch avatar Jun 20 '23 21:06 TitusKirch

It's possible to get a retry method inside the error in useGqlError ? My use case is :

  • I made a request
  • Failed, need refresh token
  • useGqlError call
  • I refresh my token + useGqlToken to put the new token
  • Recall the initial request

Thanks in advance

This functionality has been possible for quite some time now via the useGqlError utility

@Diizzayy Before I open a new issue on this, is this really possible at the moment and is the documentation simply missing? I have now tried something, but have not come to a solution. How to say at "// Handle token expiration" after the token has been freshed that the query has been executed again?

Same issue here. is there a way to recall the initial request?

bogdan12893 avatar Jan 31 '24 16:01 bogdan12893

As far as I can tell, currently it is not.

madc avatar Jan 31 '24 23:01 madc

Is there an update for this issue? I'm really interested in a way to send a request to "refresh" the token if an error occurs, and then re-invoke the original request that first caused the error.

In theory, it should be something like "forward" in apollo , but apollo is buggy and poorly documented crap

john-psina avatar Mar 18 '24 10:03 john-psina