Hi, I am using urql graphql library together with auth0-react.
According to their documentation for auth-exchange
I need to get the token on every call.
so, a simplistic graphqlClient looks like this
// index.js
import { Auth0Provider } from '@auth0/auth0-react'
import { createClient, Provider as UrqlProvider, dedupExchange, cacheExchange, fetchExchange, makeOperation } from 'urql'
import { authExchange } from '@urql/exchange-auth'
const graphClient = createClient({
url: `${CONFIG.API_BASE_URL}/authenticated/graphql`,
requestPolicy: 'network-only',
exchanges: [
dedupExchange,
cacheExchange,
authExchange({
/* auth config */
}),
fetchExchange]
})
const Base = () => {
return (
<Router history={history}>
<Auth0Provider
domain={CONFIG.AUTH0_DOMAIN}
clientId={CONFIG.AUTH0_CLIENT_ID}
audience={CONFIG.AUTH0_AUDIENCE}
connection={CONFIG.AUTH0_CONNECTION}
redirectUri={CONFIG.AUTH0_REDIRECT_URI}
logoutUri={CONFIG.AUTH0_LOGOUT_URI}
cacheLocation={navigator.userAgent.indexOf('Safari') > 0 ? 'localstorage' : 'memory'}
scope='openid profile email offline_access me:myapp'
useRefreshTokens={true}
>
<UrqlProvider value={graphClient}>
<GlobalStyle />
<App />
</UrqlProvider>
</Auth0Provider>
</Router>
)
}
ReactDOM.render(<Base />, document.getElementById('root'))
Now the problem: auth config, on another project (that’s not by me) … it can import the auth0client and does this:
authExchange({
getAuth: async ({ authState }) => {
if (!authState) {
try {
const token = await auth0Client.getTokenSilently()
return { token }
} catch (error) {
console.error('auth error', error)
return null
}
}
try {
const newToken = await auth0Client.getTokenSilently()
if (newToken) {
return { token: newToken }
}
} catch(error) {
console.error('auth error', error)
return null
}
},
addAuthToOperation: ({ authState, operation }) => {
// the token isn't in the auth state, return the operation without changes
if (!authState || !authState.token) {
return operation
}
const fetchOptions =
typeof operation.context.fetchOptions === 'function'
? operation.context.fetchOptions()
: operation.context.fetchOptions || {}
const op = makeOperation(
operation.kind,
operation,
{
...operation.context,
fetchOptions: {
...fetchOptions,
headers: {
...fetchOptions.headers,
"Authorization": `Bearer ${authState.token}`,
"Accept": 'application/json'
}
}
}
)
return op
},
}),
The auth0Client
is created from:
import { Auth0Client } from '@auth0/auth0-spa-js'
const auth0Props = {
domain: CONFIG.AUTH0_DOMAIN,
client_id: CONFIG.AUTH0_CLIENT_ID,
audience: CONFIG.AUTH0_AUDIENCE,
connection: CONFIG.AUTH0_CONNECTION,
redirect_uri: CONFIG.AUTH0_REDIRECT_URI,
logout_uri: CONFIG.AUTH0_LOGOUT_URI,
cacheLocation: navigator.userAgent.indexOf('Safari') > 0 ? 'localstorage' : 'memory',
scope: 'openid profile email offline_access me:myapp',
useRefreshTokens: true
}
const auth0Client = new Auth0Client(auth0Props)
How can I use auth0-react and use the getTokenSilently()
outside the components?
I’ve seen some similar discussions
- Using auth0 outside of React Components - #9 by dan-auth0 → no concrete solution
Most ended up making their own context.
Thanks for looking into this!