Search code examples
reactjsapolloauth0apollo-clientreact-apollo

how to add auth0 access token to react-apollo


I'm trying to add authorization token to the apollo client in react js to let the users login ...

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import { ThemeProvider } from 'react-jss';
import Theme from 'resources/theme';
import Routes from 'routes';
import './index.css';
import * as serviceWorker from './serviceWorker';
import { Auth0Provider } from "@auth0/auth0-react";
import 'bootstrap/dist/css/bootstrap.min.css';
import ReactNotification from 'react-notifications-component'
import './components/orders/fonts/NotoSansJP-Regular.otf'
import 'react-notifications-component/dist/theme.css'
import { ApolloProvider , ApolloClient, InMemoryCache } from '@apollo/client';
import { useAuth0 } from "@auth0/auth0-react";


const client = new ApolloClient({
uri: process.env.REACT_APP_API_BACK ,
headers: {
  Authorization: `Bearer ${accessToken}` // doesn’t work 
 },
  cache: new InMemoryCache()
});


ReactDOM.render(
     <Auth0Provider
    domain= {process.env.REACT_APP_AUTH0_DOMAIN }
  clientId= {process.env.REACT_APP_AUTH0_CLIENT_ID}
   redirectUri={window.location.origin}
   audience={process.env.REACT_APP_AUTH0_AUDIENCE}
   scope="warehouse"
   
  >
    <ApolloProvider client={client}> 
    <ThemeProvider theme={Theme}>
        <Router>
        <ReactNotification />
            <Routes />
        </Router>
    </ThemeProvider>,
    </ApolloProvider>
      </Auth0Provider>,
    document.getElementById('root')
);

serviceWorker.unregister();

to get the token i need to import :

import { useAuth0 } from "@auth0/auth0-react";

the add this lines :

const {  getAccessTokenSilently } = useAuth0();

but this cannot be done in index.js i think

to get the token :

 const accessToken = await getAccessTokenSilently

this what i found in the docs and from google search , but i think it cannot be done in my case , most tutorials show how to get the user data ( including the token) in a profile page but that's not wha I want .

i want to pass it to the client in index.js


Solution

  • This is what I ended up doing:

    import {
      ApolloProvider,
      ApolloClient,
      InMemoryCache,
      HttpLink,
    } from '@apollo/client';
    import { setContext } from '@apollo/link-context';
    import { useAuth0 } from '@auth0/auth0-react';
    
    const ApolloProviderWithAuth0 = ({ children }) => {
      const { getAccessTokenSilently } = useAuth0();
    
      const httpLink = new HttpLink({
        uri: process.env.REACT_APP_GRAPHQL_URI,
      });
    
      const authLink = setContext(async (_, { headers, ...rest }) => {
        let token;
        try {
          token = await getAccessTokenSilently();
        } catch (error) {
          console.log(error);
        }
    
        if (!token) return { headers, ...rest };
    
        return {
          ...rest,
          headers: {
            ...headers,
            authorization: `Bearer ${token}`,
          },
        };
      });
    
      const client = React.useRef();
    
      if (!client.current) {
        client.current = new ApolloClient({
          link: authLink.concat(httpLink),
          cache: new InMemoryCache(),
        });
      }
    
      return (
        <ApolloProvider client={client.current}>
          {children}
        </ApolloProvider>
      );
    };
    
    export { ApolloProviderWithAuth0 };
    

    And then use it as Provider in your App component.