简体   繁体   English

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

[英]Redirect Symfony2 LogoutSuccessHandler to original logout target

I need to modify my user object on logout. 我需要在注销时修改我的用户对象。 To do this, I have a security.yml that contains the following (amongst other things) - 为此,我有一个security.yml,其中包含以下内容(除其他外) -

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

...this defines a logout success handler, which is defined in services.yml like this - ...这定义了一个注销成功处理程序,它在services.yml中定义,如下所示 -

   my.security.logout_success_handler:
       class: My\Security\LogoutSuccessHandler
       arguments: ["@security.context", "@doctrine.orm.default_entity_manager"]

...finally, the business-end of my handler is like this - ...最后,我的处理程序的业务端是这样的 -

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

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

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

    // now what?

}
// ...

So, where it says "now what?" 那么,它说“现在是什么?” I understand that I need to return a Response object. 我知道我需要返回一个Response对象。 Ideally I want that response object to redirect the user to whatever is defined in logout.target in the security.yml. 理想情况下,我希望该响应对象将用户重定向到security.yml中logout.target中定义的任何内容。

Is there an easy way I can query that? 有一种简单的方法可以查询吗? Or, even better, is there another way of doing this kind of thing that doesn't require me to get involved with the request/response objects at all? 或者,更好的是,还有另一种做这种事情的方法,它不需要我参与请求/响应对象吗?

Thanks 谢谢

You could define your target as a parameter in your parameters.yml or config.yml : 您可以将目标定义为parameters.ymlconfig.yml中的parameters.yml

parameters:
    logout.target: /

And then reference this value in your security.yml : 然后在security.yml引用此值:

    logout:
        success_handler: my.logout_success_handler
        target: %logout.target%   

And/or inject it into your logout handler: 和/或将其注入您的注销处理程序:

    my.security.logout_success_handler:
        class: My\Security\LogoutSuccessHandler
        arguments: ["@security.context", "@doctrine.orm.default_entity_manager", %logout.target%]

And return a RedirectResponse with this value: 并返回具有此值的RedirectResponse

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

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

    return new RedirectResponse($this->logoutTarget);
}

So, I think I've figured out the right answer - 所以,我想我已经找到了正确的答案 -

Rather than implementing LogoutSuccessHandlerInterface and configuring a logout.success_handler , my security.yml now looks like this - 我的security.yml现在看起来像这样,而不是实现LogoutSuccessHandlerInterface并配置logout.success_handler

# ...
logout:
    handlers: [my.bundle.security.logout_handler]
# ...

...and I'm implementing Symfony\\Component\\Security\\Http\\Logout\\LogoutHandlerInterface . ...我正在实现Symfony\\Component\\Security\\Http\\Logout\\LogoutHandlerInterface Confusing naming, but this seems to be the preferred way of doing post-logout operations without having to get involved with the response object. 令人困惑的命名,但这似乎是进行后退出操作的首选方式,而无需涉及响应对象。 My implementation looks like this - 我的实现看起来像这样 -

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;
    }
}

...as you can see, the LogoutHandlerInterface provides a pre-made $response object that I can just return when I'm finished. ...正如你所看到的, LogoutHandlerInterface提供了一个预制的$response对象,我可以在完成后返回它。

You could use composition and inject the default LogoutSuccessHandler into your object and call the onLogoutSucces method on it. 您可以使用合成并将默认的LogoutSuccessHandler注入对象并在其上调用onLogoutSucces方法。

The following pseudu code shows the idea of doing it. 以下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);
    }
}

This is also the way HttpKernelInterface works in StackPHP and when you use HttpCache in your application. 这也是HttpKernelInterfaceHttpKernelInterface工作的方式以及在应用程序中使用HttpCache的方式。

Hopefully this helps, happy coding :) 希望这有帮助,快乐编码:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM