54 lines
1.4 KiB
JavaScript
54 lines
1.4 KiB
JavaScript
import axios from 'axios'
|
|
import { setCurrentRequestId } from './lib/logger.js'
|
|
|
|
const api = axios.create({
|
|
baseURL: '',
|
|
timeout: 30000,
|
|
})
|
|
|
|
// Generate a request id per outgoing call (for cross-correlation)
|
|
function newRequestId() {
|
|
// RFC4122-ish: use crypto if available
|
|
if (typeof crypto !== 'undefined' && crypto.randomUUID) {
|
|
return crypto.randomUUID()
|
|
}
|
|
return 'req-' + Math.random().toString(36).slice(2) + Date.now().toString(36)
|
|
}
|
|
|
|
// Request interceptor: auth + X-Request-ID
|
|
api.interceptors.request.use(
|
|
config => {
|
|
const token = localStorage.getItem('aars_token')
|
|
if (token) {
|
|
config.headers.Authorization = `Bearer ${token}`
|
|
}
|
|
config.headers['X-Request-ID'] = newRequestId()
|
|
return config
|
|
},
|
|
error => Promise.reject(error)
|
|
)
|
|
|
|
// Response interceptor: capture server's X-Request-ID for log correlation + 401 handling
|
|
api.interceptors.response.use(
|
|
response => {
|
|
const rid = response.headers['x-request-id']
|
|
if (rid) setCurrentRequestId(rid)
|
|
return response
|
|
},
|
|
error => {
|
|
const rid = error.response?.headers?.['x-request-id']
|
|
if (rid) setCurrentRequestId(rid)
|
|
|
|
if (error.response?.status === 401) {
|
|
localStorage.removeItem('aars_token')
|
|
// Avoid loop if already on /login
|
|
if (!window.location.pathname.startsWith('/login')) {
|
|
window.location.href = '/login'
|
|
}
|
|
}
|
|
return Promise.reject(error)
|
|
}
|
|
)
|
|
|
|
export default api
|