[英]Axios interceptor refresh token for multiple requests
I'll throw the http request because I'm calling the refresh token when it returns 401. After the refresh token response, I need to throw the previous request我将抛出http请求,因为我在返回401时调用了刷新令牌。刷新令牌响应后,我需要抛出之前的请求
SAMPLE Logın -> — 1 hours later— —> call product —> 401 —> call refresh token —> call product SAMPLE Logın -> — 1 小时后 — —> 调用产品 —> 401 —> 调用刷新令牌 —> 调用产品
I try this link a link and look this link a link but doesn't work.我尝试这个链接一个链接并查看这个链接一个链接但不起作用。
Catch the 401 error捕捉 401 错误
setInterceptors = () => {
axios.interceptors.response.use(
response => {
return response;
},
err => {
return new Promise((resolve, reject) => {
if (err.response.status === 401 && err.config && !err.config.__isRetryRequest) {
const originalRequest = err.config;
this.emit('onAutoLogin', originalRequest);
}
// throw err;
});
}
);
};
Call my action呼唤我的行动
jwtService.on('onAutoLogin', originalRequest => {
jwtService
.signInWithToken()
.then(res => {
if (res.access_token) {
originalRequest.headers['Authorization'] = 'Bearer ' + res.access_token;
Axios.request(originalRequest).then(response => {
store.dispatch({
type: ** MY PROBLEM İS HERE **
payload: response.data
});
});
}
})
.catch(err => {
jwtService.setSession(null);
});
using this link I was able to solve the problem without triggering the redux store.使用此链接,我能够在不触发 redux 存储的情况下解决问题。
let isRefreshing = false;
let failedQueue = [];
const processQueue = (error, token = null) => {
failedQueue.forEach(prom => {
if (error) {
prom.reject(error);
} else {
prom.resolve(token);
}
});
failedQueue = [];
};
axios.interceptors.response.use(
response => {
return response;
},
err => {
const originalRequest = err.config;
if (err.response.status === 401 && !originalRequest._retry) {
if (isRefreshing) {
return new Promise(function(resolve, reject) {
failedQueue.push({ resolve, reject });
})
.then(token => {
originalRequest.headers['Authorization'] = 'Bearer ' + token;
return axios(originalRequest);
})
.catch(err => {
return Promise.reject(err);
});
}
originalRequest._retry = true;
isRefreshing = true;
return new Promise(function(resolve, reject) {
axios
.post('/fooUrl/refreshToken', {
refreshToken: "fooToken"})
.then(({ data }) => {
axios.defaults.headers.common['Authorization'] = 'Bearer ' + data.fooToken;
originalRequest.headers['Authorization'] = 'Bearer ' + data.fooToken;
processQueue(null, data.fooToken);
resolve(axios(originalRequest));
})
.catch(err => {
processQueue(err, null);
store.dispatch(showMessage({ message: 'Expired Token' }));
reject(err);
})
.then(() => {
isRefreshing = false;
});
});
}
return Promise.reject(err);
}
);
Here's a quick way I implemented it.这是我实现它的一种快速方法。 I found it a bit simpler to reason about the code.我发现推理代码更简单一些。 I've adapted it from this solution: HERE我已经从这个解决方案中调整了它:这里
let refreshTokenPromise: null | Promise < any > ;
instance.interceptors.response.use(r => {
const {
data
} = r;
if (data.errors && data.errors[0].message === "AUTH_EXPIRED") {
if (!refreshTokenPromise) {
refreshTokenPromise = fetchRefreshToken().then(data => {
refreshTokenPromise = null;
return data;
});
}
return refreshTokenPromise.then(token => {
if (r.config.headers) r.config.headers["Authorization"] = token;
return instance.request(r.config);
});
}
return r;
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.