In my React Native utility, I get an entry token and a refresh token after login.
There’s a frequent perform to name the entry token once more utilizing the refresh token when the entry token is invalid
On my residence web page, there are 6 APIs, however when the entry token will get invalid these 6 APIs parallelly name to the frequent perform and refresh the entry token. That is making that particular person get blocked.
Tips on how to stop this? blocking the remainder of the APIs with a flag when the primary API’s token turns into invalid is just not an possibility as a result of, earlier than the primary response, all of the APIs could have refreshed the entry token.
The handleResponse
perform will get triggered first then the code reaches getNewToken
funtions then it reaches the dispatch(logout());
as a result of the decision for accesstoken doesn’t grow to be success and the app crashes as a result of logout is known as a number of instances.
const handleResponse = async (
res: ApiResponse<BaseResponseProp, BaseResponseProp> | null,
) => {
if (res?.information?.error === 'invalid_token') {
let tokenVal;
attempt {
if (token.refresh_token) {
tokenVal = await getNewToken(token.refresh_token);
} else {
//refresh the general public token
tokenVal = await refreshPublicToken();
}
if (tokenVal?.access_token && tokenVal?.access_token.size > 0) {
const newTokenHeader = {
Authorization: `Bearer ${tokenVal.access_token}`,
};
invoke({
requestHeader: { ...requestHeader, ...newTokenHeader },
requestBody,
requestParams,
requestQuery,
url: formattedEndpoint,
onResultCallback,
onErrorCallback,
});
dispatch(setToken(tokenVal));
} else {
setInvalidToken(true);
navigation.dispatch(
StackActions.substitute(NAVIGATION_SCREENS.ROOT),
);
return;
}
return;
} catch (e) {
const newToken = await refreshPublicToken();
dispatch(setToken(newToken));
return;
}
}
const err = new CustomError(
res?.information?.error || res?.originalError?.message,
res?.information?.standing || 200,
);
if (typeof onErrorCallback === 'perform') {
onErrorCallback(err);
} else if (typeof onError === 'perform') {
onError(err as CustomError);
}
handleParseError(err);
} else {
const responseData = res?.information as unknown as R;
if (renderData) {
setData(res?.information);
}
if (typeof onResultCallback === 'perform') {
onResultCallback(res?.information as unknown as R);
} else if (typeof onResult === 'perform') {
onResult(res?.information);
}
}
};
const getNewToken = async (refToken: string) => {
let formattedEndpoint = ENDPOINT.LOGIN;
let tokenVal = {};
const header = { refresh_token: refToken };
const requestQuery = {
...REFRESH_AUTH_HEADERS,
...header,
};
const queryParams = new URLSearchParams({
...requestQuery,
}).toString();
formattedEndpoint = `${formattedEndpoint}?${queryParams}`;
const refreshResponse = await api.put up<LoginSuccess>(
formattedEndpoint,
{},
{
headers: basicAuthHeaders,
},
);
if (refreshResponse.standing === 200) {
tokenVal = {
access_token: refreshResponse.information?.access_token,
refresh_token: refreshResponse.information?.refresh_token,
expires_in: refreshResponse.information?.expires_in,
sort: 'non-public',
};
} else {
// The logout will get referred to as a number of instances and app crashes
dispatch(logout());
tokenVal = {
access_token: null,
token_type: null,
refresh_token: null,
expires_in: null,
scope: null,
id_token: null,
sort: 'public',
};
tokenVal = await refreshPublicToken();
navigation.dispatch(StackActions.substitute(NAVIGATION_SCREENS.ROOT));
}
return tokenVal;
};