Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 61bb0cc23c |
@@ -1,81 +0,0 @@
|
|||||||
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;
|
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { Button } from '@SharePoint/rencredit_uikit';
|
||||||
|
|
||||||
|
export default function Header(){
|
||||||
|
const[appName, setAppName] = useState<string>('');
|
||||||
|
useEffect( () => {
|
||||||
|
setAppName(document.getElementById('page__header-block')?.dataset.app_name || '');
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="header-block__header-container">
|
||||||
|
<div className="header-container__block">
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
type = 'button'
|
||||||
|
onClick = {() => document.location.href='/public/menu'}
|
||||||
|
text = 'ЛОГОТИП ТУТ'
|
||||||
|
ui = 'secondaryPurple'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
type = 'button'
|
||||||
|
onClick = {() => document.location.href='/public/menu'}
|
||||||
|
text = 'Меню'
|
||||||
|
ui = 'secondaryPurple'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="header-container__block__app-name">{appName}</div>
|
||||||
|
</div>
|
||||||
|
<div className="header-container__block">
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
type = 'button'
|
||||||
|
onClick = {() => document.location.href='/public/request_access'}
|
||||||
|
text = 'Заказать доступ'
|
||||||
|
ui = 'secondaryPurple'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
type = 'button'
|
||||||
|
onClick = {() => document.location.href='/public/logout'}
|
||||||
|
text = 'Выход'
|
||||||
|
ui = 'secondaryPurple'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,13 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use \App\Http\Controllers;
|
|
||||||
use App\Http\Middleware\AuthenticateMagic;
|
|
||||||
|
|
||||||
Route::get('/', function () {
|
Route::get('/', function () {
|
||||||
return view('welcome');
|
return view('welcome');
|
||||||
});
|
});
|
||||||
|
|
||||||
//ГАВРИЛОВ. добавить without middleware AuthMagicApi?
|
|
||||||
//Фоновое обновление санктум токена, если api вернул 401 (санктум протух), а сессия еще "жива"
|
|
||||||
Route::get('/silent_token_refresh', [Controllers\LoginController::class, 'silentRefreshUserSanctumToken'])->withoutMiddleware([AuthenticateMagic::class]);
|
|
||||||
|
|||||||
Reference in New Issue
Block a user