diff --git a/resources/js/api.js b/resources/js/api.js new file mode 100644 index 0000000..616707f --- /dev/null +++ b/resources/js/api.js @@ -0,0 +1,81 @@ +import axios from 'axios'; + +/** + * @author dgavrilov + * Пока в этом скрипте реализован axios иaнтерцептор для api запросов, отправляемых с фронта. Своего рода посредник для совершения "пред" и "пост" действий/проверок во время отправки api запроса + */ + +//ГАВРИЛОВ +//переименуй файл на axios + +//Инстанс api контура +const api = axios.create({ + baseURL: '/public/api/', + withCredentials: true, + headers: { + 'content-type': 'application/json', + 'Accept': 'application/json', + } +}) + +//Инстанс web контура +const web = axios.create({ + baseURL: '/public/', + withCredentials: true, + headers: { + 'content-type': 'application/json', + 'Accept': 'application/json', + } +}) + +//Гаврилов. +//Перехват запросов. Добавить подстановку bearer token? +// api.interceptors.request.use(); + +let isRefreshing = false, //Флаг выполнения запроса на обновления токена. Пока он иеет значение true, остальные запросы, попадающие в очередь из за полученной 401 ошибки кладутся в массив queueRqsts + queueRqsts = []; //запросы, которые получили 401 ошибку, одновремменно кладутся в эту переменную в виде промимсов, чтобы быть вызванными позднее, когда будет результат обновления токена превого запроса +//Если api ответ возвращает 401 ошибку, отправляем web запрос на роут фонового обновления санктум токена, где происходит проверка сессии, срока жизни санктум токена и его обновление, при удовлетворяющих условиях + +//Перехват ответов api +api.interceptors.response.use( + response => response, + async error => { + const originalRequest = error.config; //Параметры вызываемого запроса + // originalRequest._retry = true; + if (error.response?.status === 401) { + if (isRefreshing) { + return new Promise((resolve, reject) => { + queueRqsts.push({ + resolve: () => resolve(api(originalRequest)), + reject + }) + }) + } else { + isRefreshing = true; + try { + let resultRefresh; + //ГАВРИЛОВ. запись данных формы в session storage при неудачном silent regresh token. Чтобы после перезагрузки страницы подтянуть данные из session storage в форму? тогда придется заморачиваться с компонентом подтягивания данных из session storage при рендеринге страницы + resultRefresh = await web.get('silent_token_refresh') + if (!resultRefresh.data.original.data.token_refresh) { + throw new Error('Сессия истекла'); + } + queueRqsts.forEach(pending => { + pending.resolve(); + }) + return api(originalRequest); + } catch (error) { + queueRqsts.forEach(pending => pending.reject(error)) + isRefreshing = false; + queueRqsts = []; + window.location.href = '/public/login'; + } finally { + isRefreshing = false; + queueRqsts = []; + } + } + } + return true; + } +) + +export default api; diff --git a/routes/web.php b/routes/web.php index 86a06c5..8d255cd 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,7 +1,13 @@ withoutMiddleware([AuthenticateMagic::class]);