loggedIn()) { HTTP::redirect('/'); } $session = Session::instance(); $request = Request::$current; if ($request->method() === HTTPRequest::POST) { return $session->get(self::PENDING_KEY) !== null ? $this->handleCodeStep($session) : $this->handleCredentialsStep($session); } return $this->renderContent('login', [ 'error' => null, 'step' => $session->get(self::PENDING_KEY) !== null ? 'code' : 'credentials', ]); } /** * Первый шаг — логин/пароль. При успехе не авторизует сразу, а переводит * на шаг с кодом (см. Auth::verifyCredentials() — проверка без сессии). * * @param Session $session * @return string * @throws MyException */ protected function handleCredentialsStep(Session $session): string { $request = Request::$current; $validation = Validation::factory($request->post()) ->label('login', 'Логин') ->label('password', 'Пароль') ->rule('login', 'required') ->rule('password', 'required'); if ($validation->check() && Auth::instance()->verifyCredentials($request->post('login'), $request->post('password'))) { $session->set(self::PENDING_KEY, $request->post('login')); $session->set(self::REMEMBER_KEY, $request->post('remember') !== null); return $this->renderContent('login', ['error' => null, 'step' => 'code']); } return $this->renderContent('login', ['error' => 'Неверный логин или пароль', 'step' => 'credentials']); } /** * Второй шаг — код с почты (заглушка STUB_CODE). При успехе — Auth::forceLogin() * (второй фактор пройден, пароль повторно не проверяется), с учётом «запомнить меня». * * @param Session $session * @return string * @throws MyException */ protected function handleCodeStep(Session $session): string { $request = Request::$current; $login = $session->get(self::PENDING_KEY); if ($request->post('code') === self::STUB_CODE) { Auth::instance()->forceLogin($login, (bool)$session->get(self::REMEMBER_KEY, false)); $session->delete(self::PENDING_KEY)->delete(self::REMEMBER_KEY); HTTP::redirect('/'); } return $this->renderContent('login', ['error' => 'Неверный код', 'step' => 'code']); } /** * @return never */ public function logoutAction(): never { Auth::instance()->logout(); HTTP::redirect('/login'); } }