Getting access tokens inside another hook/reusable code for getting access tokens

Question:

I am using auth0 to authorize access from my React application to my API. I am using JWT access tokens for every call. For every call to the API, I’m using the following custom hook to retrieve an access token with the scope passed as an argument:

(this previously used async/await, but removed it to make it synchronous while debugging)

const useAuth0Header = (scope) => {
  const {
    getAccessTokenSilently,
    getAccessTokenWithPopup,
  } = useAuth0();

  let token;
  try {
    token = getAccessTokenSilently({
      audience: `${API_URL}`,
      scope,
    });
  } catch (err) {
    token = getAccessTokenWithPopup({
      audience: `${API_URL}`,
      scope,
    });
  }

  return token;

I put this into a different file for reusability so whenever I call my API, I can just call the hook with the appropriate scope. However, this presents a problem because many of my API calls happen within useEffect(), which I can’t call another hook inside of.

I’ve tried moving my API calls outside of useEffect(), but this get’s very messy with a lot of if statements to decide if we need to get updated data from the API or not. Example:

  if (drafts.length === 0) {
    useAuth0Header('read:drafts').then((res) => {
      axios
        .get(
          `${API_URL}/liftplan/drafts`,
          {
            headers: { Authorization: `Bearer ${res}` },
          },
        )
        .then((response) => {
          setDrafts(response.data.data.drafts);
        });
    });
  }

With my code getting progressively more hacky, I am curious if there is a better way to go about this. How can I use getAccessToken(Silently/WithPopup) in my app that has many API calls triggered from React’s useEffect().

Some related questions:

  • Is it bad practice to have a separate scope and access token for every API call?
  • How can I minimize calls to getAccessToken(Silently/WithPopup) while still ensuring I’m authorizing every endpoint?

I am fairly new to React and completely new to Auth0.

Supporting Documentation:

Documentation: Auth0 React SDK Quickstarts: Call an API

Hi @dramsay1996

Welcome to Auth0 community :wave:

Here is an example how to call getAccessTokenSilently inside the hook. GitHub - auth0/auth0-react: Auth0 SDK for React Single Page Applications (SPA)

Regarding your question using seperate scopes for each call, the best practice is to use a minimum scope access token and only get sensitive scopes on as need to basis. For example: if a customer going to make a payment and payment API needs a senstive scopes then go ahead renewing token based of that new scope. So it all depends on how you designed your API’s and senstivity of the operations in the application.

Hope this helps

Thanks
Jeff

Hi @jeff.ishar1

Thanks! This is helpful, although I’m curious if it is possible to put this token retrieval code in an external function so I could re-use it on many different API calls (of varying scopes). Is this possible?

And thank you for the guidance on scoping access tokens. That makes sense.

Thanks
Dustin

Hi @dramsay1996

Yes you can achieve that, take a look here. You can pass url, scopes etc in the options from your components.

Cheers
Jeff