Мне нужно изменить свой пользовательский объект при выходе из системы. Для этого у меня есть security.yml, который содержит следующие (среди прочего) –
#... logout: success_handler: my.logout_success_handler target: / #...
… это определяет обработчик успеха выхода, который определяется в services.yml, как это –
my.security.logout_success_handler: class: My\Security\LogoutSuccessHandler arguments: ["@security.context", "@doctrine.orm.default_entity_manager"]
… наконец, бизнес-конец моего обработчика похож на это –
// ... public function onLogoutSuccess(Request $request) { $user = $this->securityContext->getToken()->getUser(); // ... do stuff with the user object.... $this->em->flush(); // now what? } // ...
Итак, где он говорит «теперь что?» Я понимаю, что мне нужно вернуть объект Response. В идеале я хочу, чтобы объект ответа перенаправлял пользователя на все, что определено в logout.target в security.yml.
Есть ли простой способ, я могу запросить это? Или, что еще лучше, есть ли другой способ делать такие вещи, которые не требуют от меня вообще участвовать в объектах запроса / ответа?
благодаря
Вы можете определить свою цель как параметр в parameters.yml
или config.yml
:
parameters: logout.target: /
И затем укажите это значение в security.yml
:
logout: success_handler: my.logout_success_handler target: %logout.target%
И / или введите его в обработчик вылета:
my.security.logout_success_handler: class: My\Security\LogoutSuccessHandler arguments: ["@security.context", "@doctrine.orm.default_entity_manager", %logout.target%]
И возвратите RedirectResponse
с этим значением:
// Assign the 3. constructor parameter to the instance variable $logoutTarget public function onLogoutSuccess(Request $request) { // ... return new RedirectResponse($this->logoutTarget); }
Вы можете использовать композицию и LogoutSuccessHandler
по умолчанию LogoutSuccessHandler
в свой объект и вызывать на onLogoutSucces
метод onLogoutSucces
.
Следующий псевдо-код показывает идею его выполнения.
class MyLogoutSuccessHandler implements \LogoutSuccessHandler { protected $original; public function __construct(OriginalLogoutSuccesHandler $original) { $this->original = $original; } public function onLogoutSuccess(Request $request) { // do stuf your want and delegate to the original return $this->original->onLogoutSuccess($request); } }
Это также способ, которым HttpKernelInterface
работает в StackPHP и когда вы используете HttpCache
в своем приложении.
Надеюсь, это поможет, счастливое кодирование 🙂
Итак, я думаю, что я понял правильный ответ –
Вместо того, чтобы внедрять LogoutSuccessHandlerInterface
и настраивать logout.success_handler
, мой security.yml теперь выглядит следующим образом:
# ... logout: handlers: [my.bundle.security.logout_handler] # ...
… и я реализую Symfony\Component\Security\Http\Logout\LogoutHandlerInterface
. Сбивание имен, но это, по-видимому, является предпочтительным способом выполнения операций после выхода из системы, без необходимости вмешиваться в объект ответа. Моя реализация выглядит так:
namespace My\Bundle\Security; use Symfony\Component\Security\Http\Logout\LogoutHandlerInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Request; use Doctrine\ORM\EntityManager; /** * Do post logout stuff */ class LogoutHandler implements LogoutHandlerInterface { /** * @var EntityManager */ protected $em; /** * Constructor * @param EntityManager $em */ public function __construct(EntityManager $em) { $this->em = $em; } /** * Do post logout stuff */ public function logout(Request $request, Response $response, TokenInterface $authToken) { $user = $authToken->getUser(); // do stuff with the user object... $this->em->flush(); return $response; } }
… как вы можете видеть, LogoutHandlerInterface
предоставляет предварительно созданный объект $response
который я могу просто вернуть, когда LogoutHandlerInterface
.