英文:
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 = "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;
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// >>>>> 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;
}
<!-- end snippet -->
Regardless, you shouldn't refresh the token after it has already expired. It's not secure
Best of luck with your project:)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论