Home > Back-end >  Periodically fetching the auth token while the async function is running
Periodically fetching the auth token while the async function is running

Time:09-20

I have this authFetch function that fetches the token and updates it in mongo and token variable.

 const authFetch = async () => {

let authCollection = client.db("WheelPros_data").collection("auth");
TokenFromDB = await authCollection.find({ _id: 1 }).toArray();
({ accessToken: token, time: lastFetchedAuth } = TokenFromDB[0] || [{ accessToken: null, time: 0 }])
// console.log(new Date().getTime() / 1000 - lastFetchedAuth)

let axiosConfig = {
  headers: {
    "Content-Type": "application/json",
    accept: "application/json",
  },
};

await axios({
  method: "POST",
  data: {
    userName: process.env.WHEELPROS_USERNAME,
    password: process.env.PASSWORD,
  },
  url: `${process.env.PROD_API_URL}/auth/v1/authorize`,
  axiosConfig,
})
  .then(async (res) => {
    const { accessToken } = res.data;
    authCollection.updateOne(
      { _id: 1 },
      {
        $set: {
          accessToken: accessToken,
          time: new Date().getTime() / 1000,
          Date: new Date(),
        },
      }, {
      upsert: true
    }
    );
    console.log("newAccessToken : ", accessToken)
    token = await accessToken
    console.log("inside token var = ", token)

    console.log("------------------Auth Updated------------------");

  })
  .catch((err) => {
    console.log("AXIOS ERROR: ", err);
  });
}
await authFetch()
// console.log("ourside token var = ", token)

setInterval(authFetch, 3590000)

Problem arises when i call another async function to fetch the submodels. After 1 hour the token expires and that is why we have setInterval function to update the token but it does not update the token and i get hit with the 403 error

Below is the modelFetch function

 const fetchSubmodels = async () => {
const modelDataFromDB = await collection
  .find({ modelData: { $exists: true } })
  .toArray();
console.log(modelDataFromDB.length)
modelDataFromDB.forEach(async (modeldata) => {
  // await fetchToken().catch(console.error)

  let dataSearch = modeldata.modelData.split(';')

  await axios
    .get(
      `${process.env.PROD_API_URL}/${dataSearch[0]}/makes/${dataSearch[1]}/models/${dataSearch[2]}/submodels`,
      {
        headers: {
          Authorization: `Bearer ${token}`,
          "Content-Type": "application/json",
        },
      }
    )
    .then(async function ({ data }) {

      await collection.updateOne(
        { modelData: modeldata.modelData },
        {
          $set: {
            submodels: data
          },
        }
      );
      // handle success
      console.log(`pushing the submodels ${data} to ${modeldata.modelData} `)

    })
    .catch(async function (error) {
      // handle error
      console.log(error);

    })

})
}
await fetchSubmodels()
clearInterval(authFetch)

Any insights would be helpful!

CodePudding user response:

Like array.map, array.forEach does not await the result of the function that it calls. In your case, this means that the axios.get statements for each entry in modelDataFromDB send out all requests synchronously, while token still has its original value. (Therefore they should never lead to 403, if they reach the backend in time.)

What's more, fetchSubmodels does not await anything and therefore resolves after all these requests have been sent out. At that point in time await fetchSubmodels() is completed, therefore clearInterval(authFetch) is executed almost immediately, and the setInterval has no effect.

While this does not yet explain the 403 responses, it is certainly not what you intended.

If you replace

modelDataFromDB.forEach(async (modeldata) => {
  ...
})

with

for (var modeldata of modelDataFromDB) {
  ...
}

the requests will be sent consecutively, and fetchSubmodels will await the response of the last request.

  • Related