【问题标题】:Redirect Symfony2 LogoutSuccessHandler to original logout target将 Symfony2 LogoutSuccessHandler 重定向到原始注销目标
【发布时间】:2014-03-17 03:05:04
【问题描述】:

我需要在注销时修改我的用户对象。为此,我有一个 security.yml,其中包含以下内容(除其他外) -

#...
    logout:
        success_handler: my.logout_success_handler
        target: /
#...

...this 定义了一个注销成功处理程序,它在 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 对象。理想情况下,我希望该响应对象将用户重定向到 security.yml 中 logout.target 中定义的任何内容。

有没有一种简单的方法可以查询?或者,更好的是,有没有另一种方式来做这种事情,根本不需要我参与请求/响应对象?

谢谢

【问题讨论】:

    标签: php symfony


    【解决方案1】:

    所以,我想我已经找到了正确的答案 -

    我的security.yml现在看起来像这样,而不是实现LogoutSuccessHandlerInterface和配置logout.success_handler——

    # ...
    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 对象,我可以在完成后返回。

    【讨论】:

    • 这里的区别是你总是在操纵你的用户,即使注销不成功。
    • 实际上,LogoutHandler(s) 似乎是在 LogoutSuccessHandler 之后调用的,这意味着一定会成功注销。见github.com/symfony/symfony/blob/…
    • 只有在不成功的情况下才退出。
    【解决方案2】:

    您可以使用组合并将默认的LogoutSuccessHandler 注入您的对象并在其上调用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 时的方式。

    希望这会有所帮助,祝你编码愉快:)

    【讨论】:

    • 这很有趣,它让我想到了我认为可能是正确的答案,我现在将其发布......
    • 原来的handler类其实是DefaultLogoutSuccessHandler
    • 在 services.yml 中注入的服务名称是什么?
    【解决方案3】:

    您可以将目标定义为parameters.ymlconfig.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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-05
      • 2013-04-09
      • 1970-01-01
      • 2017-07-13
      • 1970-01-01
      • 2011-10-11
      • 2017-06-01
      • 2012-11-05
      相关资源
      最近更新 更多