first()->tokens()->delete(); session()->invalidate(); #Гаврилов //ВЫЗОВ СКРИПТА НА СТАРОМ МЭДЖИКЕ ДЛЯ УДАЛЕНИЯ КУК АУТЕНТИФИКАЦИИ (ЛОГИН И ГРУППЫ) return redirect('/login'); } #Гаврилов //РАЗНЕСИ ЛОГИКУ МЕЖДУ МЕТОДАМИ, А ТО ПОКА ВСЯ ЛОГИКА В ОДНОМ МЕТОД DLAPCHECK public function ldapCheckUser (Request $request) { if ($request->_auth_login) { if (Auth::attempt([ 'samaccountname' => $request->_auth_login, 'password' => $request->_auth_password, ])) { $userGroups = $this->getUserGroups($request->_auth_login); session()->put('_auth_login', $request->_auth_login); session()->put('_auth_groups', $userGroups); //Если пользователь зашел впервые - записываем его логин в таблицу users. Она нужна для корректного взаимодействия с пакетом Sanctum $user = User::firstOrCreate( ['login' => $request->_auth_login], ); //Удаляем все предыдущие sanctum токены пользователя User::where('login', $request->_auth_login)->first()->tokens()->delete(); //Определяем на какую страницу нужно бросить пользователя после успешной аутентификации. По умолчанию кидаем в меню $redirectUrl = session()->has('_auth_prev_page') ? session()->get('_auth_prev_page') : ('/menu'); $isAdminFlag = in_array($this->adminGroup, $userGroups); //Кладем в сессию информацию о том является ли пользователь админом session()->put('is_admin', $isAdminFlag); //Устанавливаем в пользовательский сервис параметры пользователя UserContext::setUserLogin($request->_auth_login); UserContext::setUserADGroups($userGroups); UserContext::setUserEmails($userGroups); UserContext::setIsAdminFlag($isAdminFlag); $userPermissions = $this->authorizationService->getUserAppPermissions(); UserContext::setUserAppPermissions($userPermissions); //Генерим Sanctum токен, чтобы поместить его в куки при редиректе $token = $user->createToken('sanctum-token', [ 'permissions' => $userPermissions //Устанавливаем время жизни sanctum токена синхронно с временем жизни сессии из конфига ], now()->addHours(config('app.session_life_time') / 60))->plainTextToken; return redirect($redirectUrl) ->withCookie('sanctum_token', $token, 60 * 24, '/', null, true, true); } else { #Гаврилов //СООБЩЕНИЕ ОБ ОШИБКЕ ПРИ НЕУДАЧНОЙ АУТЕНТИФИКАЦИИ return redirect('/login'); } } } /** * Метод фонового обновления санктум токена при получении 401 ошибки в ответе api ендпоинта * * @param Request $request * @return void */ public function silentRefreshUserSanctumToken(Request $request) { //Если сессия истекла - возвращаем 401 ошибку и редирект на /login в axios if (!Auth::check()) { $this->apiResponder->setDto(new ApiResponseDto(null, ['token_refresh' => false])); return response()->json($this->apiResponder->error(), 401); } $token = $request->cookie('sanctum_token'); $accessToken = \Laravel\Sanctum\PersonalAccessToken::findToken($token); //Если токен "протух" - продлеваем его на час if (now()->diffInMinutes($accessToken->expires_at, false) < 1) { $accessToken->update( [ 'expires_at' => now()->addHours(1) ] ); $this->apiResponder->setDto(new ApiResponseDto(null, ['token_refresh' => true])); return response()->json($this->apiResponder->success()); } else { //Если токен еще "свежий" - значит причина 401 ошибки в чем-то другом. Не обновляем токен, просто возвращаем 401 ошибку и редирект на /login в axios $this->apiResponder->setDto(new ApiResponseDto(null, ['token_refresh' => false])); return response()->json($this->apiResponder->error(), 401); } } /** * Метод получает группы пользователя из ldap * * @param string $userLogin логин пользователя, чьи группы получаем * @return array */ public function getUserGroups($userLogin) { $userGroups = []; $ldapUser = LdapUserInfo::findBy('samaccountname', $userLogin); $ldapUser->memberOf; if (isset($ldapUser->memberOf)) { foreach ($ldapUser->memberOf as $ldapGroupInfo) { $CN_group = substr($ldapGroupInfo, 0, stripos($ldapGroupInfo, ",")); $groupName = str_replace(array('CN=', '\\'), array('', ''), $CN_group); $clearGroupName = trim($groupName); if ($clearGroupName && $clearGroupName == str_replace($this->unnecessaryGroups, '', $clearGroupName)) { $userGroups[] = $clearGroupName; } } } return $userGroups; } }