在 nextjs 中未正确返回更新的对象

Updated object not being returned properly in nextjs

所以基本上我正在开发一个使用身份验证的 nextjs 应用程序。我有 2 个函数,我在每个页面加载时 运行。第一个检查 jwt cookie 是否存在,如果不存在则调用另一个函数来验证令牌。此函数来自 wrapper.getServerSideProps 运行,并作为 ctx 在上下文中传递。此功能按预期工作。

export const checkServerSideCookie = (ctx) => {
   const access = getCookie("access", ctx.req);
   const refresh = getCookie("refresh", ctx.req);
   if (access && refresh) {
      return checkAuthentication(access, refresh);
   } else return { isAuthenticated: false, token: null };
};

第二个函数是令牌验证器,这就是问题所在。我有一个对象,我打算在验证成功时更新它,如果不成功则不理会它。这是函数

export const checkAuthentication = (access, refresh) => {
   const obj = {
      isAuthenticated: false,
      token: null,
   };
   const body = JSON.stringify({ token: access });
   axios
      .post("http://localhost:8000/api/jwtoken/verify/", body, {
         headers: {
            "Content-Type": "application/json",
         },
      })
      .then((res) => {
         obj.isAuthenticated = true;
         obj.token = access;
      })
      .catch((err) => {
         // call new token function using refresh
         console.log("it doesnt work");
      });
   return obj;
};

问题是 .then 确实更新了对象,而当我 console.log(obj) 在 .then 它向 return 显示正确的对象,但是当我 return 对象时,它仍然保持 false 和 null 的初始值。我不明白这是什么问题。我尝试在 .then 本身中执行 return 但它遇到了这个错误 TypeError: Cannot destructure property 'isAuthenticated' of 'Object(...)(...)' as it is undefined。 这里的问题是什么?一切似乎都不错,但更新后的对象未 returned。

当您调用 checkAuthentication 时,它会立即 returns obj 具有默认属性。您在函数中指定了一个异步操作,但是您不必等到它完成。您必须按以下方式重建函数:

export const checkAuthentication = (access, refresh) => {
   const obj = {
      isAuthenticated: false,
      token: null,
   };
   const body = JSON.stringify({ token: access });
   return new Promise((resolve, reject) => {
    axios
      .post("http://localhost:8000/api/jwtoken/verify/", body, {
         headers: {
            "Content-Type": "application/json",
         },
      })
      .then((res) => {
         resolve({
           isAuthenticated: true,
           token: access
         })
      })
      .catch((err) => {
         // call new token function using refresh
         console.log("it doesnt work");
         reject();
      });
    });
};

然后按以下方式调用您的函数:

checkAuthentication(access, refresh)
  .then(console.log)
  .catch(console.log)

当然,您有多种选择可以使您的函数更简洁,例如使用 async/await 等,但这应该让您快速了解错误所在。

axios.post 是异步的,你在 returning obj 之前它被 api 响应中的数据填充,你可以使用 async/await 来解决:

export const checkAuthentication = async (access, refresh) => {
  const obj = {
    isAuthenticated: false,
    token: null
  };

  const body = JSON.stringify({ token: access });

  try {
    const res = await axios.post("http://localhost:8000/api/jwtoken/verify/", body, {
      headers: {
        "Content-Type": "application/json"
      }
    });

    obj.isAuthenticated = true;
    obj.token = access;
  } catch (e) {
    // do something with the error
    // call new token function using refresh
    console.log("it doesnt work");
  }

  return obj;
};

用法(checkAuthentication 现在 return 承诺):

checkAuthentication(a, b).then((obj) => {
  console.log(obj);
});