0

Be it a class or functional component, I want a function to get executed just before the return statement each time the component is called. This function would connect to mongodb and check if any changes are to be made in the token. If yes, it would automatically send to the login route.

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175

1 Answers1

0

You need to create a function which handles that you have a proper request sender. This is a promisified request sender:

function makeRequest (method, url, succ, err) {
  return new Promise(function (resolve, reject) {
    var xhr = new XMLHttpRequest();
    xhr.open(method, url);
    xhr.onload = function () {
      if (this.status >= 200 && this.status < 300) {
        resolve(xhr.response);
        succ(response);
      } else {
        reject({
          status: this.status,
          statusText: xhr.statusText
        });
        err(response);
      }
    };
    xhr.onerror = function () {
      reject({
        status: this.status,
        statusText: xhr.statusText
      });
      err(xhr.statusText);
    };
    xhr.send();
  });
}

// Example:

makeRequest('GET', 'http://example.com')
.then(function (datums) {
  console.log(datums);
})
.catch(function (err) {
  console.error('Augh, there was an error!', err.statusText);
});

Source: How do I promisify native XHR?

Now, let's create a function which awaits that promise:

async function syncedRequest(method, url, succ, err) {
    await makeRequest(method, url, succ, err);
}

Implement success and error callbacks:

function successTokenCallback(response) {
    this.token = response;
}

function errorTokenCallback(message) {
    console.log(message);
}

and a token refresher:

function refreshToken(value) {
    syncedRequest(method, url, successTokenCallback, errorTokenCallback);
    //do something with successTokenCallback.token
    return value;
}

and you can do this wherever you want a token refresh to happen before the return:

return refreshToken(value);

The problem I see with this is that you are making your requests synchronous, which is in general an anti-pattern. You should aim to avoid blocking your Javascript flow because you wait for a request whenever possible. However, if it is absolutely necessary, you can do the above.

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
  • Thanks mate I appreciate your help! Will try to implement this. Btw what would be the best practice to go with - 1. Making requests and verifying token data during routing in react. Or 2. While verifying the jwt token as a middleware in backend, connect to db and check if token values are upto date. My main concern is if for eg. the role of an user is updated by the admin, I need to make sure that the role value in the token is immediately updated. If not updated, I will log the user out and clear the token so that he can re-login and get the updated token. – Ripunjoy Saikia Nov 17 '20 at 15:50
  • @RipunjoySaikia you could also use some in-memory storage on the server, like Redis to store expired tokens until their normal end-of-life, so you would not have to send a request to the database each time you do a request. You would check for in-memory storage instead. Also, you could destroy the session of the user on server-side. Or, checking for a token could be done via the server under the hood, without the client-side having to send a separate request for it. You have many possible options. – Lajos Arpad Nov 18 '20 at 11:52