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

Jez*_*Jez 8 php symfony

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

#...
    logout:
        success_handler: my.logout_success_handler
        target: /
#...
Run Code Online (Sandbox Code Playgroud)

...这定义了一个注销成功处理程序,它在services.yml中定义,如下所示 -

   my.security.logout_success_handler:
       class: My\Security\LogoutSuccessHandler
       arguments: ["@security.context", "@doctrine.orm.default_entity_manager"]
Run Code Online (Sandbox Code Playgroud)

...最后,我的处理程序的业务端是这样的 -

// ...
public function onLogoutSuccess(Request $request)
{

    $user = $this->securityContext->getToken()->getUser();

    // ... do stuff with the user object....
    $this->em->flush();

    // now what?

}
// ...
Run Code Online (Sandbox Code Playgroud)

那么,它说"现在是什么?" 我知道我需要返回一个Response对象.理想情况下,我希望该响应对象将用户重定向到security.yml中logout.target中定义的任何内容.

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

谢谢

Lei*_*eif 8

您可以将目标定义为您parameters.yml或中的参数config.yml:

parameters:
    logout.target: /
Run Code Online (Sandbox Code Playgroud)

然后在您的参考中引用此值security.yml:

    logout:
        success_handler: my.logout_success_handler
        target: %logout.target%   
Run Code Online (Sandbox Code Playgroud)

和/或将其注入您的注销处理程序:

    my.security.logout_success_handler:
        class: My\Security\LogoutSuccessHandler
        arguments: ["@security.context", "@doctrine.orm.default_entity_manager", %logout.target%]
Run Code Online (Sandbox Code Playgroud)

RedirectResponse使用此值返回a :

// Assign the 3. constructor parameter to the instance variable $logoutTarget

public function onLogoutSuccess(Request $request)
{
    // ...

    return new RedirectResponse($this->logoutTarget);
}
Run Code Online (Sandbox Code Playgroud)


Jez*_*Jez 7

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

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

# ...
logout:
    handlers: [my.bundle.security.logout_handler]
# ...
Run Code Online (Sandbox Code Playgroud)

......而我正在实施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;
    }
}
Run Code Online (Sandbox Code Playgroud)

......正如你所看到的,它LogoutHandlerInterface提供了一个预制的$response对象,我可以在完成后返回.


Hen*_*kov 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这也是HttpKernelInterface在StackPHP中以及HttpCache在应用程序中使用时的方式.

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