2014-02-17 48 views
8

我需要在註銷時修改我的用戶對象。要做到這一點,我有一個包含以下(除其他事項外)一個security.yml -將Symfony2 LogoutSuccessHandler重定向到原始註銷目標

#... 
    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中定義的任何內容。

有沒有簡單的方法可以查詢?或者,更好的是,還有另一種做這種事情的方式,不需要我參與請求/響應對象呢?

感謝

回答

5

所以,我想我已經想通了正確的答案 -

比實現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對象,我可以在完成時返回。

+0

這裏的區別在於,即使註銷不成功,您也始終在操縱用戶。 –

+0

實際上,看起來'LogoutHandler's *在'LogoutSuccessHandler'之後被調用*,這意味着註銷成功保證會發生。見https://github.com/symfony/symfony/blob/f828aee7f749009a574eee0a1ad5bfd092b0d488/src/Symfony/Component/Security/Http/Firewall/LogoutListener.php#L108-L118 – Jez

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

這也是方式StackPHP HttpKernelInterface作品,當你在你的應用程序中使用HttpCache

希望這有助於,快樂編碼:)

+0

這是非常有趣的,它讓我對我認爲可能是正確的答案,我現在會發布... – Jez

+0

原始處理程序類實際上是'DefaultLogoutSuccessHandler' – Gregoire

+0

什麼是注入服務的服務名稱.yml? –