Я ищу способ зарегистрировать пользователя из приложения Symfony 2, но не смог найти способ сделать это правильно.
Я пробовал описанный здесь подход: Symfony2: как вручную вывести пользователя вручную в контроллер?
$this->get('security.context')->setToken(null); $this->get('request')->getSession()->invalidate();
Он работает нормально, когда « запомнить меня » отключен, однако, когда я его включаю, он не работает. Похоже, что пользователь автоматически повторно аутентифицируется обратно этим куки-файлом.
remember_me: key: "%secret%" lifetime: 31536000 path: / domain: ~ always_remember_me: true
Каков правильный способ регистрации пользователя из приложения Symfony 2? Нужно ли дополнительно удалить этот файл cookie с сервера?
Возможно, вам придется явно вызвать метод save()
( Documentation ) сеансового хранилища.
Заставить сеанс сохранять и закрывать.
Кроме того, вы можете попросить удалить сеанс – и / или remember_me -cookies через заголовки ответов.
Имя сессии -cookie настраивается как контейнер-параметр framework.session.name
и по умолчанию имеет значение session.name
из вашего php.ini .
$cookieName = $this->container->getParameter('framework.session.name'); $response->headers->clearCookie( $cookieName );
Имя memory_me -cookie можно настроить в вашей конфигурации security
.
security: firewalls: your_firewall: remember_me: name: neverforget # <- cookie-name
Благодаря @nifr я смог решить эту проблему. Вот пулебезопасное пошаговое руководство для входа пользователя из приложения Symfony 2 вручную.
Symfony уже реализует функции регистрации пользователя и удаления файлов cookie. Существует LogoutListener
который делегирует эти действия для пары обработчиков выхода: CookieClearingLogoutHandler
и SessionLogoutHandler
. Я думаю, что лучший способ действий – назвать этих обработчиков, а не реализовывать такую низкоуровневую логику самостоятельно. Однако я не могу найти способ сделать это.
Это решение для Symfony 2.6. Разница заключается в security.token_storage
.
parameters.yml
: # parameters.yml parameters: session.name: SESS session.remember_me.name: LONGSESS
config.yml
чтобы использовать первый параметр для имени сеанса: # config.yml framework: session: name: "%session.name%"
security.yml
чтобы использовать второй параметр для запоминания имени сеанса: # security.yml security: firewalls: demo_secured_area: remember_me: name: "%session.remember_me.name%"
Вы можете использовать такой код внутри прослушивателя событий ядра, если хотите.
// SomeController.php /** * @Route("/terminate", name="app.terminate") */ public function terminateAction() { // Logging user out. $this->get('security.token_storage')->setToken(null); // Invalidating the session. $session = $this->get('request')->getSession(); $session->invalidate(); // Redirecting user to login page in the end. $response = $this->redirectToRoute('app.login'); // Clearing the cookies. $cookieNames = [ $this->container->getParameter('session.name'), $this->container->getParameter('session.remember_me.name'), ]; foreach ($cookieNames as $cookieName) { $response->headers->clearCookie($cookieName); } return $response; }
Вот реализация прослушивателя событий ядра, который заставит пользователей выйти из строя на основе свойства entity: Запуск пользователя из приложения Symfony 2 с помощью прослушивателя событий ядра .
Я надеюсь, что это помогает.
@ Слав Фомин II
Symfony уже реализует функции регистрации пользователя и удаления файлов cookie. Существует LogoutListener, который делегирует эти действия для пары обработчиков выхода: CookieClearingLogoutHandler и SessionLogoutHandler. Я думаю, что лучший способ действий – назвать этих обработчиков, а не реализовывать такую низкоуровневую логику самостоятельно. Однако я не могу найти способ сделать это.
Почему бы просто не создать службу, которая их вызывает?
Я просмотрел Symfony\Component\Security\Http\Firewall\LogoutListener
и протестировал его, что он вызывает 2 службы во время выхода из системы (Symfony 3.2.9).
$tokenBasedRememberMeServices
, кстати, удаляет cookie с $tokenBasedRememberMeServices
.
<?php declare(strict_types=1); namespace MyProject\Security\Listener; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; use Symfony\Component\Security\Http\Logout\DefaultLogoutSuccessHandler; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Security\Http\Logout\SessionLogoutHandler; use Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices; final class LogoutListener { private $sessionLogoutHandler; private $tokenBasedRememberMeServices; private $defaultLogoutSuccessHandler; private $tokenStorage; public function __construct( SessionLogoutHandler $sessionLogoutHandler, TokenBasedRememberMeServices $tokenBasedRememberMeServices, DefaultLogoutSuccessHandler $defaultLogoutSuccessHandler, TokenStorage $tokenStorage ) { $this->sessionLogoutHandler = $sessionLogoutHandler; $this->tokenBasedRememberMeServices = $tokenBasedRememberMeServices; $this->defaultLogoutSuccessHandler = $defaultLogoutSuccessHandler; $this->tokenStorage = $tokenStorage; } public function logout(Request $request): void { $token = $this->tokenStorage->getToken(); $response = $this->defaultLogoutSuccessHandler->onLogoutSuccess($request); $this->sessionLogoutHandler->logout($request, $response, $token); $this->tokenBasedRememberMeServices->logout($request, $response, $token); } }