1

所以基本上我正在开发一个使用身份验证的 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确实更新了对象,当我在.then中使用 console.log(obj) 时,它显示了要返回的正确 obj,但是当我返回 obj 时,它仍然保留 false 和 null 的初始值. 我不明白问题是什么。我尝试在 .then 本身中进行返回,但它通过了这个错误 TypeError: Cannot destructure property 'isAuthenticated' of 'Object(...)(...)' as it is undefined。这里有什么问题?一切看起来都很好,但更新后的 obj 没有返回。

4

2 回答 2

2

axios.post是异步的,你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现在返回一个承诺):

checkAuthentication(a, b).then((obj) => {
  console.log(obj);
});
于 2021-04-08T22:37:33.413 回答
1

当您调用checkAuthentication它时,它会立即返回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等,但这应该可以让您快速了解问题所在。

于 2021-04-08T22:36:00.857 回答