#symfony #security #symfony-4.2
#symfony #Безопасность #symfony-4.2
Вопрос:
В security.yaml
файле мы определяем управление доступом для различных маршрутов и РОЛЕЙ, которые могут получить доступ к этому же маршруту.
Но как мы можем настроить пользователя, который вошел в систему, но не может вернуться на страницу / login, пока он не выйдет из системы и «ROLE_USER» не изменится на «anon».
Я новичок в Symfony 4.2.
Контроллер:
namespace AppController;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentRoutingAnnotationRoute;
use SymfonyComponentSecurityHttpAuthenticationAuthenticationUtils;
use SymfonyComponentSecurityCoreAuthorizationAuthorizationCheckerInterface;
//use SymfonyComponentSecurityCoreExceptionAccessDeniedException;
class SecurityController extends AbstractController
{
/**
* @Route("/login", name="login")
*/
public function login(Request $request, AuthenticationUtils $utils, AuthorizationCheckerInterface $authChecker)
{
// to check whether user is looged-in
if ($authChecker->isGranted('IS_AUTHENTICATED_FULLY')) {
die('Logged in user cannot access this page');
}
// get the login error if there is one
$error = $utils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $utils->getLastUsername();
return $this->render('security/login.html.twig', [
'last_username' => $lastUsername,
'error' => $error
]);
}
public function logout()
{
# code...
}
Комментарии:
1. Не было бы лучше, если бы вы перенаправляли прошедших проверку подлинности пользователей со страницы входа на стартовую страницу (или любую соответствующую страницу)?
Ответ №1:
Вы не можете запретить доступ зарегистрированному пользователю к странице входа путем редактирования security.yml
. Все пользователи приложения Symfony, независимо от того, вошли они в систему или нет, будут иметь базовую привилегию доступа: IS_AUTHENTICATED_ANONYMOUSLY
и Symfony не имеет исключительной роли для пользователя, не вошедшего в систему.
Однако вы можете добиться того же, проверив, вошел пользователь в систему или нет в вашем контроллере, и выполнить перенаправление или выдать AccessDeniedException
:
public function login($name, AuthorizationCheckerInterface $authChecker)
{
if ($authChecker->isGranted('IS_AUTHENTICATED_FULLY')) {
throw new AccessDeniedException('Logged in user cannot access this page');
}
// ...
}
Комментарии:
1. Какой класс для AccessDeniedException??
2. оператор if неверен. Это должно быть ‘if ($authChecker->isGranted(‘IS_AUTHENTICATED_FULLY’)) { создать новое исключение AccessDeniedException (‘Зарегистрированный пользователь не может получить доступ к этой странице’); }’
3. Хорошее место, я скопировал пример из Symfony doc и не редактировал его.
4. Какой класс для AccessDeniedException??
5. Вы упомянули перенаправление, и это намного лучший вариант, чем выдача исключения. С точки зрения UX я думаю, что ужасно путать аутентифицированного пользователя с
AccessDeniedException
.
Ответ №2:
Как я упоминал в комментариях, на мой взгляд, отправка AccessDeniedException
уже зарегистрированному пользователю не является хорошим подходом. Что подумали бы ваши пользователи? Если я уже вошел в систему, почему я не могу получить доступ к странице, к которой я обычно могу получить доступ, даже если я не вошел в систему.
Поэтому я настоятельно рекомендую перенаправлять зарегистрированных пользователей при доступе к /login
пути на стартовую страницу вашего приложения.
Просто адаптируйте блок if-condition в методе login
вашего SecurityController
:
if ($authChecker->isGranted('IS_AUTHENTICATED_FULLY)) {
$this->redirectToRoute('name of the route - replace with an appropriate value');
}
Вы должны позаботиться о том, чтобы маршрут, на который вы перенаправляете, не вызывал другого перенаправления и, таким образом, не помещал вас в бесконечный цикл.