Monday, 11 January 2021

Interceptor for fetch and fetch retry? (Javascript)

I am trying to create an interceptor for fetch in javascript (React to be more specific). It should get the result from every fetch that gets called, and if it is an 401 error it should initiate a new fetch call to another route to get a cookie (a refresh token). Then, the original fetch call should be tried again (because now the user is logged in).

I have managed to trigger the new fetch call and send back the cookie for each, but I got these two problems below:

  1. I do not now how to retry the fetch call after the refresh token has been recieved. Is that possible? I found the fetch-retry npm (https://www.npmjs.com/package/fetch-retry) but not sure how and if I can implement that on an interceptor when it should be done for the original fetch call.

  2. I seem to be doing something wrong with async await (I think), because the intercept is not waiting for the fetch call before returning the data (the statuscode on the original fetch seems to be 401 and not 200 which it should be after we get the cookie. I also tried to return the response of the fetch inside the interceptor but that returned undefined).

Any idea about how to solve this? Anyone who have done something similar?

Below is my code:

(function () {
  const originalFetch = fetch;
  fetch = function() {
      return originalFetch.apply(this, arguments).then(function(data) {

          if(data.status === 401) {
            console.log('not authorized, trying to get refresh cookie..')

            const fetchIt = async () => {
              let response = await fetch(`/api/token`, {
                  method: 'POST',
                  credentials: 'include', 
                  headers: {
                      'Content-Type': 'application/json'
                  },
              });
          }
        fetchIt();
          } 
         return data

      }); 
  };
})();

EDIT: To make it more clear what I am after. I need an interceptor like I described above to work so I don't have to do something like this after every fetch call:

getData() {
        const getDataAsync = async () => {
            let response = await fetch(`/api/loadData`, { method: 'POST' });

           if(response.status === 401) {
            let responseT = await fetch(`/api/token`, {
                method: 'POST',
                credentials: 'include', 
                headers: {
                    'Content-Type': 'application/json'
                },
            });

            if(responseT.status === 401) {
                return responseT.status
            }

            if(responseT.status === 200) {
            response = await fetch(`/api/loadData`, { method: 'POST' });
            }
           }

          let data = await response.json();
            //Do things with data
        };
        getDataAsync();
    };

So basically the interceptor should:

  1. Check if there is a 401, if so then:
  2. fetch api/token
  3. If api/token returns 401, it should just return that.
  4. If api/token returns 200, it should run original fetch again


from Interceptor for fetch and fetch retry? (Javascript)

No comments:

Post a Comment