56 lines
1.8 KiB
TypeScript
56 lines
1.8 KiB
TypeScript
import axios from 'axios'
|
|
import keycloak from '@/services/keycloak'
|
|
import { useAuthStore } from '@/store/authStore'
|
|
|
|
const api = axios.create({
|
|
baseURL: '/api',
|
|
timeout: 30000,
|
|
})
|
|
|
|
api.interceptors.request.use((config) => {
|
|
const token = localStorage.getItem('access_token')
|
|
if (token) config.headers.Authorization = `Bearer ${token}`
|
|
return config
|
|
})
|
|
|
|
api.interceptors.response.use(
|
|
(res) => res,
|
|
async (error) => {
|
|
const original = error.config
|
|
if (error.response?.status === 401 && !original._retry) {
|
|
original._retry = true
|
|
const refreshToken = localStorage.getItem('refresh_token')
|
|
if (refreshToken) {
|
|
try {
|
|
const { data } = await axios.post('/api/auth/refresh', { refresh_token: refreshToken })
|
|
localStorage.setItem('access_token', data.access_token)
|
|
original.headers.Authorization = `Bearer ${data.access_token}`
|
|
return api(original)
|
|
} catch {
|
|
// Refresh failed — try re-exchanging via Keycloak
|
|
try {
|
|
await keycloak.updateToken(10)
|
|
if (keycloak.token) {
|
|
const { data } = await axios.post('/api/auth/keycloak', { kc_token: keycloak.token })
|
|
localStorage.setItem('access_token', data.access_token)
|
|
localStorage.setItem('refresh_token', data.refresh_token)
|
|
original.headers.Authorization = `Bearer ${data.access_token}`
|
|
return api(original)
|
|
}
|
|
} catch {
|
|
// Keycloak session also expired — force re-login
|
|
}
|
|
useAuthStore.getState().logout()
|
|
keycloak.login()
|
|
}
|
|
} else {
|
|
useAuthStore.getState().logout()
|
|
keycloak.login()
|
|
}
|
|
}
|
|
return Promise.reject(error)
|
|
}
|
|
)
|
|
|
|
export default api
|