Spaces:
Sleeping
Sleeping
File size: 2,219 Bytes
8fd091f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | import axios from 'axios'
const api = axios.create({
baseURL: import.meta.env.VITE_API_URL || '/api',
timeout: 15000,
headers: { 'Content-Type': 'application/json' },
withCredentials: true,
})
// βββ Request interceptor: attach JWT βββββββββββββββββββββββββββββββββββββββββ
api.interceptors.request.use(config => {
const token = localStorage.getItem('access_token')
if (token) config.headers.Authorization = `Bearer ${token}`
return config
}, error => Promise.reject(error))
// βββ Response interceptor: auto-refresh token ββββββββββββββββββββββββββββββββ
let isRefreshing = false
let failedQueue = []
const processQueue = (error, token = null) => {
failedQueue.forEach(prom => error ? prom.reject(error) : prom.resolve(token))
failedQueue = []
}
api.interceptors.response.use(
response => response,
async error => {
const originalRequest = error.config
if (error.response?.status === 401 && !originalRequest._retry) {
if (isRefreshing) {
return new Promise((resolve, reject) => {
failedQueue.push({ resolve, reject })
}).then(token => {
originalRequest.headers.Authorization = `Bearer ${token}`
return api(originalRequest)
})
}
originalRequest._retry = true
isRefreshing = true
try {
const refresh = localStorage.getItem('refresh_token')
if (!refresh) throw new Error('No refresh token')
const { data } = await axios.post('/api/auth/token/refresh/', { refresh })
localStorage.setItem('access_token', data.access)
processQueue(null, data.access)
originalRequest.headers.Authorization = `Bearer ${data.access}`
return api(originalRequest)
} catch (err) {
processQueue(err, null)
localStorage.removeItem('access_token')
localStorage.removeItem('refresh_token')
window.location.href = '/login'
return Promise.reject(err)
} finally {
isRefreshing = false
}
}
return Promise.reject(error)
}
)
export default api
|