将Symfony2 LogoutSuccessHandler重定向到原始注销目标

时间:2014-02-17 17:27:03

标签: php symfony

我需要在注销时修改我的用户对象。为此,我有一个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对象。理想情况下,我希望该响应对象将用户重定向到security.yml中logout.target中定义的任何内容。

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

由于

3 个答案:

答案 0 :(得分:8)

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

答案 1 :(得分:7)

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

而不是实现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对象,我可以在完成后返回。

答案 2 :(得分:6)

您可以使用合成并将默认LogoutSuccessHandler注入对象并在其上调用onLogoutSucces方法。

以下pseudu代码显示了这样做的想法。

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时的方式。

希望这有助于,快乐的编码:)