刷新和访问令牌问题 axios 和 React Native

huangapple go评论132阅读模式
英文:

Refresh and Access token issue axios and react native

问题

// 我有以下的代码

// 这部分是用于刷新令牌,它完美地工作

export async function refreshTokenGenerator() {

const url = RefreshCurrentTokenURL;

const refreshTokenGeneratedFirst = newUser.getRefreshToken();

const response = await axios
.post(url, {

  refreshToken: refreshTokenGeneratedFirst,
})
.catch((error) => {

  console.log(
    "🤠 ~ file: auth.js:118 ~ refreshTokenGenerator ~ error cant refresh token",
    error
  );
});

const newRefreshTokenGenerated = response.data.refreshToken;

// 将新生成的刷新令牌分配给用户模型

// 刷新令牌循环运行良好,没有覆盖 RT 的错误

const assignNewRefreshTokenToUserModel = newUser.setRefreshToken(
newRefreshTokenGenerated
);

// 访问令牌循环正常运行,

// 每当收到错误 401 时使用它,因为这意味着 AT 已过期

const newAccessTokenGenerated = response.data.token;

return newAccessTokenGenerated;
}

// 这部分用于验证菜单并获取类别

async function authenticateMenu() {

const url = CategoriesAuthUrl;

let userToken = newUser.getToken();

const authStr = "Bearer ".concat(userToken);

const options = {
method: "GET",
headers: {
Authorization: authStr,
},
url: url,
};

const response = await axios(options).catch(async (error) => {

if (error.response.status === 401) {

  // 应该调用 refreshToken 来刷新访问和刷新令牌

  console.log("Error 401 unauthorized");


  const newUserToken = await updateAccessToken();

  userToken = newUserToken;
}
console.log(
  "😅 ~ file: menu.js:28 ~ authenticateMenu ~ Error getting categories from API call",
  error
);

});

const fetchedCategories = response.data;

console.log(
"🤠 ~ file: menu.js:40 ~ authenticateMenu ~ fetchedCategories",
fetchedCategories
);

return fetchedCategories;
}

// 获取类别

export async function getCategories() {
return authenticateMenu();
}

在我的 HomeScreen 中,我像这样调用获取类别

useEffect(() => {
async function fetchCatHandler() {

  const categoriesFetched = await getCategories().catch((error) => {
    console.log(
      "🧭 ~ file: HomeScreen.js:63 ~ fetchCatHandler ~ error from fetching categories from Home screen",
      error
    );
  });

  setParsedCategories(categoriesFetched);
}

fetchCatHandler();

async function getUserName() {
  setUserName(await newUser.getUserName());
}

getUserName();

}, []);

// 代码在访问令牌过期之前都运行得很完美。因此,每当我收到错误.response.status === 401 时,我调用 updateAccessToken 函数,该函数重新生成新的访问和刷新令牌,并将这些保存在用户模型中

export async function updateAccessToken() {

console.log("updateAccessToken called");

const newGeneratedTokenAfterExpiration = await refreshTokenGenerator();

newUser.setToken(newGeneratedTokenAfterExpiration);

const userToken = newGeneratedTokenAfterExpiration;

return userToken;
}

英文:

// I have the following code

// this is for refreshing the token and it works perfectly fine

export async function refreshTokenGenerator() {

  const url = RefreshCurrentTokenURL;

  const refreshTokenGeneratedFirst = newUser.getRefreshToken();

  const response = await axios
    .post(url, {

      refreshToken: refreshTokenGeneratedFirst,
    })
    .catch((error) => {

      console.log(
        "🚀 ~ file: auth.js:118 ~ refreshTokenGenerator ~ error cant refresh token",
        error
      );
    });

  const newRefreshTokenGenerated = response.data.refreshToken;

  //  assign the new generated refresh token to the user model

  // Refresh token loop works fine, no error from overriding the RT

  const assignNewRefreshTokenToUserModel = newUser.setRefreshToken(
    newRefreshTokenGenerated
  );

  // access token loops works fine,

  //   use it whenever u receive error 401 because it means that AT expired

  const newAccessTokenGenerated = response.data.token;

  return newAccessTokenGenerated;
}

// This part is for authenticating the menu and fetching the categories

async function authenticateMenu() {

  const url = CategoriesAuthUrl;

  let userToken = newUser.getToken();

  const authStr = "Bearer ".concat(userToken);

  const options = {
    method: "GET",
    headers: {
      Authorization: authStr,
    },
    url: url,
  };

  const response = await axios(options).catch(async (error) => {

    if (error.response.status === 401) {

      // should call the refreshToken to refresh the access and refresh token

      console.log("Error 401 unauthorized");


      const newUserToken = await updateAccessToken();

      userToken = newUserToken;
    }
    console.log(
      "😡 ~ file: menu.js:28 ~ authenticateMenu ~ Error getting categories from API call",
      error
    );
  });

  const fetchedCategories = response.data;

  console.log(
    "🚀 ~ file: menu.js:40 ~ authenticateMenu ~ fetchedCategories",
    fetchedCategories
  );

  return fetchedCategories;
}

//  Get Categories

export async function getCategories() {
  return authenticateMenu();
}

**In my HomeScreen I call the fetch categories like this**

 useEffect(() => {
    async function fetchCatHandler() {

      const categoriesFetched = await getCategories().catch((error) => {
        console.log(
          "🟥 ~ file: HomeScreen.js:63 ~ fetchCatHandler ~ error from fetching categories from Home screen",
          error
        );
      });

      setParsedCategories(categoriesFetched);
    }

    fetchCatHandler();

    async function getUserName() {
      setUserName(await newUser.getUserName());
    }

    getUserName();
  }, []);

// The code works perfectly fine until the access token is expired. Hence, whenever I receive error.response.status === 401 I call the function updateAccessToken which regenerates new access and refresh token and I save these in the user model

// when I fetch the categories it works fine up until the access token expires and I get the error [AxiosError: Request failed with status code 401].

// Any idea what am I missing/doing wrong??

   export async function updateAccessToken() {

  console.log("updateAccessToken called");

  const newGeneratedTokenAfterExpiration = await refreshTokenGenerator();
  

  newUser.setToken(newGeneratedTokenAfterExpiration);

  const userToken = newGeneratedTokenAfterExpiration;


  return userToken;
}

答案1

得分: 1

一旦你收到了401错误,响应就结束了。如果之后修改令牌,它不会改变响应。在收到401并生成新令牌后,你应该发送一个带有新令牌的新请求,并返回其响应。

    async function authenticateMenu() {

      const url = CategoriesAuthUrl;

      let userToken = newUser.getToken();

      const authStr = "Bearer ".concat(userToken);

      const options = {
        method: "GET",
        headers: {
          Authorization: authStr,
        },
        url: url,
      };

      const response = await axios(options).catch(async (error) => {

        if (error.response.status === 401) {

          // 应该调用refreshToken来刷新访问和刷新令牌

          console.log("Error 401 unauthorized");


          const newUserToken = await updateAccessToken();

          userToken = newUserToken;
          //>>>>>> This doesn't effect the current req/resposnse. After reseting the token you should send another request, with the new token
          //>>>>>> 这不会影响当前的请求/响应。在重置令牌后,您应该发送另一个带有新令牌的请求
        }
        console.log(
          "🙅‍♂️ ~ file: menu.js:28 ~ authenticateMenu ~ Error getting categories from API call",
          error
        );
      });

      const fetchedCategories = response.data;

      console.log(
        "🙈 ~ file: menu.js:40 ~ authenticateMenu ~ fetchedCategories",
        fetchedCategories
      );

      return fetchedCategories;
    }

无论如何,在令牌已经过期后,你不应该刷新令牌。这不安全。

祝你的项目顺利!:)

英文:

Once you've gotten an 401, the response is over. It doesn't change the response if you alter the token afterward. After getting a 401 and generating a new token, you should've sent a new request with the new token and return its response instead.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

async function authenticateMenu() {

  const url = CategoriesAuthUrl;

  let userToken = newUser.getToken();

  const authStr = &quot;Bearer &quot;.concat(userToken);

  const options = {
    method: &quot;GET&quot;,
    headers: {
      Authorization: authStr,
    },
    url: url,
  };

  const response = await axios(options).catch(async (error) =&gt; {

    if (error.response.status === 401) {

      // should call the refreshToken to refresh the access and refresh token

      console.log(&quot;Error 401 unauthorized&quot;);


      const newUserToken = await updateAccessToken();

      userToken = newUserToken;
      //&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;
      // &gt;&gt;&gt;&gt;&gt; This doesn&#39;t effect the current req/resposnse. After reseting the token you should send another request, with the new token
      //&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;
    }
    console.log(
      &quot;&#128545; ~ file: menu.js:28 ~ authenticateMenu ~ Error getting categories from API call&quot;,
      error
    );
  });

  const fetchedCategories = response.data;

  console.log(
    &quot;&#128640; ~ file: menu.js:40 ~ authenticateMenu ~ fetchedCategories&quot;,
    fetchedCategories
  );

  return fetchedCategories;
}

<!-- end snippet -->

Regardless, you shouldn't refresh the token after it has already expired. It's not secure

Best of luck with your project:)

huangapple
  • 本文由 发表于 2023年1月6日 10:34:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/75026388.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定