Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4dcf13b9c9 | |||
| 70356583d1 |
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
//очереди для чтения нотификаций
|
||||||
|
use Illuminate\Support\Facades\Redis;
|
||||||
|
/**
|
||||||
|
* Глобальный посредник аутентификации на платформе Magic для всех роутов платформы
|
||||||
|
*/
|
||||||
|
class AuthenticateMagic
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handle an incoming request.
|
||||||
|
*
|
||||||
|
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||||
|
*/
|
||||||
|
public function handle(Request $request, Closure $next): Response
|
||||||
|
{
|
||||||
|
UserContext::setUserAppPermissions($user->tokens()->latest()->first()->abilities['permissions']);
|
||||||
|
#Гаврилов
|
||||||
|
//Насксолько я помню, это связано с механизмом получения нотификаций на фронте (через отдельный компонент React) на случай, если нотификации формируются на бэке и должны читаться фронтом сразу при рендеринге. Обычно, нотификации формируются после запроса с фронта, например, при fetch запросе на отправку заявки на такси и сразу же рендерятся на этой же странице после выполнения fetch запроса, но бывают ситуации, когда пользователя с бэке редиректит на другую страницу, в результате чего тяряется "контекст" нотификаций. Я как-то настраивал чтение редис очередей на любой странице, чтобы при рендеринге любой страницы сразу проверялась есть ли непрочитенная нотификация. Если есть - она читается, отображается и удаляется из очереди. Но может конкретно строка ниже связана с тестированием , уже не помню
|
||||||
|
Redis::setex('notifications', 60, 123);
|
||||||
|
return $next($request);
|
||||||
|
} else {
|
||||||
@@ -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;
|
|
||||||
@@ -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