diff --git a/app/Http/Middleware/AuthenticateMagicApi.php b/app/Http/Middleware/AuthenticateMagicApi.php new file mode 100644 index 0000000..5571805 --- /dev/null +++ b/app/Http/Middleware/AuthenticateMagicApi.php @@ -0,0 +1,61 @@ +is('api/silent_token_refresh')) { + // return $next($request); + // } + //Если пользователь в рамках сессии обращается к api ендпоинтам из приложения, он не всегда может установить заголовок с sanctum токеном (например, переходя по ссылкке ). В этом случае, проверяем куки и устанавливаем заголовок оттуда, так как при аутентификации пользовательский логин кладется в куки. Это позволяет нам не устанвливать заголовк в каждом fetch запросе на фронте + if ($request->is('api/*') && ($token = $request->cookie('sanctum_token'))) { + $request->headers->set("Authorization", "Bearer $token"); + } + //Переопределяем поведение в случае возникновения ошибки при стандартной аутентификации. Стандартное поведение перебрасывает на страницу login, мы же возвращаем 401 ошибку, так как понимаем, что пользователь обратился по api + //DGAVRILOV. ПОВЕДЕНИЕ, ОПИСАННОЕ ВЫШЕ, ПРИВОДИТ К ОШИБКЕ. ЕСЛИ ПОЛЬЗОВАТЕЛЬ ОТПРАВИЛ API ЗАПРОС С ФРОНТА И ЕГО СЕССИЯ ПРОТУХЛА, ВОЗВРАЩАЕТСЯ 401 ОШИБКА ВО ВКЛАДКЕ NETWORK, НО ПОЛЬЗОВАТЕЛЯ НЕ ПЕРЕБРАСЫВАЕТ НА СТРАНИЦУ /LOGIN. ЕСЛИ ПОПРАВИТЬ ПОСРЕДНИК WEB АУТЕНТИФИКАЦИИ, ТО ЭТОЙ ПРОБЛЕМЫ НЕ БУДЕТ? БУДЕТ ПЕРЕБРАСЫВАТЬ НА СТРАНИЦУ LOGIN СО СТРАНИЦЫ, ОТКУДА СОВЕРЩАЛСЯ ВЫЗО API ЕНДПОИНТА? СКОРЕЕ ВСЕГО НЕТ, НУЖНО БУДЕТ ПРИ ВЫЗОВЕ API КАК-ТО ПЕРЕХВАТЫВАТЬ 401 ОШИБКУ И ОТПРАВЛЯТЬ НА СТРАНИЦУ /LOGIN + try { + //Стандартная аутентификация по санктум токену (проверяется срок жизни) + $this->authenticate($request, $guards); + //$token = $request->user()->currentAccessToken(); + //Если токен истекает менее через 60 минут, продлеваем его на 2 часа. Ситуации, что сессия протухла, а токен продолжает жить не может случиться, так как апи запросы с фронта отправляют куку аутентификации, которая проверяется при $this->authenticate. Если она протухла, возвратится 401 ошибку. + // if ($token->expires_at->diffInMinutes(now()) < 60) { + // $token->update( + // [ + // 'expires_at' => now()->addHours(2) + // ] + // ); + // } + //После успешной аутентификации Sanctum обогащаем UserService параметрами пользователя (логин, роли приложения) + #Гаврилов + //ПОКА НЕ ДОБАВЛЯЮ ГРУППЫ AD B EMAILS, ТАК КАК В WEB КОНТУРЕ ОНИ ОПРЕДЕЛЯЮТСЯ ПРИ AD АУТЕНТИФИКАЦИИ И ПОЛУЧЕННЫЕ ЗНАЧЕНИЯ СКЛАДЫВАЮТСЯ В SESSION. В API КОНТУРЕ ДОСТУПА К СЕССИИ НЕТ - ПРОВОДИТЬ AD АУТЕНТИФИКАЦИЮ НЕ ПОЛУЧИТС БЕЗ ПАРОЛЯ ПОЛЬЗОВАТЕЛЯ, КОТОРЫЙ НИГДЕ НЕ ХРАНИТСЯ. ПОЭТОМУ, ЕСЛИ ПОНАДОБИТСЯ ДОСТАВАТЬ В API КОНТУРЕ ГРУППЫ ПОЛЬЗОВАТЕЛЯ, ПРИ AD АУТЕНТИФИКАЦИИ ПОНАДОБИТСЯ КЛАСТЬ AD ГРУППЫ ПОЛЬЗОВАТЕЛЯ И ЕГО EMAILS В ПОЛЕ ABILITIES ТАБЛИЦЫ PERSONAL ACCESS TOKENS ПО АНАЛОГИИ С PERISSIONS + #Гаврилов + //НУЖНО ЛИ ОБОГАЩАТЬ USERcoNTEXT НИЖЕ, ЕСЛИ ПРИ WEB АУТЕНТИФИКАЦИИ КОНТЕКСТ УЖЕ ДОЛЖЕН БЫЛ БЫТЬ ОБОГАЩЕН. вЕРОЯТНО, ЭТО НУЖНО ДЛЯ ОБРАБОТКИ ЧИСТО API ЗАПРОСОВ (БЕЗ ВХОДА В СИСТЕМУ), НО НАДО ПРОВЕРИТЬ + UserContext::setUserLogin($request->user()->login); + UserContext::setUserAppPermissions($request->user()->currentAccessToken()->abilities['permissions']); + } catch (AuthenticationException $auth) { + if ($request->is('api/*')) { + return response()->json([ + #Гаврилов + //СКОРРЕКТИРУЙ ИНФОРМАЦИЮ О ВОЗВРАЩАЕМОЙ ОШИБКЕ? + 'error' => 'Unauthenticated', + 'message' => 'Invalid or missing authentication token' + ], 401); + } + + throw $auth; + } + return $next($request); + } +}