Axios sử dụng interceptors để tự động lấy token từ refreshToken
import axios from "axios";
import { BASE_URL_API } from "./config";
export const API = axios.create({
baseURL: BASE_URL_API,
headers: {
Accept: 'application/json',
}
})
API.interceptors.request.use((config) => {
const token = localStorage.getItem('token');
config.headers.Authorization = `Bearer ${token}`;
return config;
}, (error) => {
return Promise.reject(error);
})
API.interceptors.response.use((response) => response, async (error) => {
const originRequest = error.config;
if (!originRequest._retry && error.response.status == 401) {
originRequest._retry = true;
try {
const refreshToken = localStorage.getItem('refreshToken');
if (!refreshToken) {
throw new Error("Missing refresh token");
}
const response = await axios.post(BASE_URL_API + 'refresh', {
'refreshToken': refreshToken,
});
if (response.status === 200 && response.data?.token) {
const data = await response.data;
localStorage.setItem('token', data.token);
originRequest.headers['Authorization'] = `Bearer ${data.token}`;
return API(originRequest);
}
else {
window.location.href = '/login';
return Promise.reject(new Error('Lỗi '))
}
} catch (error) {
window.location.href = '/login';
return Promise.reject(error);
}
}
return Promise.reject(error);
})
Ở đây mình dùng throw new Error và Promise.reject ở 2 nơi vì lý do sau
So sánh | throw new Error(...) |
return Promise.reject(new Error(...)) |
---|---|---|
Dùng trong | async/await hoặc synchronous code |
Hàm không async , hoặc interceptor, Promise chain |
Dừng function ngay | ✔️ | ❌ (chỉ trả về Promise lỗi) |
Tự động tạo Promise lỗi | ✔️ nếu trong async |
❌ bạn tạo rõ ràng |
Rõ ràng trong Promise context | ❌ | ✔️ |