2017-06-22 40 views
1

我在Symfone 2.8 webapp項目中使用FOSUserBundle。目前,用戶在退出時只需重定向到主頁。這應該被更改爲可以(可選地)顯示個人信息(例如提醒即將到來的任務或簡單的「Goodbey USERNAME」而不是「Goodbey」)的「個人」註銷頁面...如何獲取FOSUserBundle註銷頁面上的用戶詳細信息?

因此,我需要訪問/使用當前註銷用戶的詳細信息。但是由於用戶剛剛註銷,我無法再訪問用戶對象了?

如何解決這個問題?

這是我的配置使用:

// config 
security: 
    ... 
    providers: 
     fos_userbundle: 
      id: fos_user.user_provider.username_email 

    firewalls: 
     main: 
      ... 
      logout: 
       path: fos_user_security_logout 
       target: /logoutpage 


// route 
<route id="user_logout" path="/logoutpage" methods="GET"> 
    <default key="_controller">AppBundle:Default:logout</default> 
</route> 


// Controller action 
public function logoutAction() { 
    $loggedOutUser = HOW_TO_GET_USER(???); 

    $template = 'AppBundle:Default:logout.html.twig'; 
    return $this->render($template, array('user' => $loggedOutUser)); 
} 

回答

1

的清潔方法是用戶名/數據會話保存EventSubscriber /監聽偵聽一個security.interactive_logout事件中。

由此引起的兩個問題是:

  • 沒有被默認LogoutHandler
  • 的symfony派出沒有註銷事件每默認配置會清除註銷會話

您可以更改會話清除行爲通過設置invalidate_sessionfalse

security: 
    firewalls: 
    main: 
     # [..] 
     logout: 
     path: 'fos_user_security_logout' 
     target: '/logoutpage' 
     invalidate_session: false # <- do not clear the session 
     handlers: 
      - 'Namespace\Bridge\Symfony\Security\Handler\DispatchingLogoutHandler' 

對於您可以創建一個註銷處理這樣的註銷事件:

class DispatchingLogoutHandler implements LogoutHandlerInterface 
{ 
    /** @var EventDispatcherInterface */ 
    protected $eventDispatcher; 

    /** 
    * @param EventDispatcherInterface $event_dispatcher 
    */ 
    public function __construct(EventDispatcherInterface $event_dispatcher) 
    { 
     $this->eventDispatcher = $event_dispatcher; 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function logout(Request $request, Response $response, TokenInterface $token) 
    { 
     $this->eventDispatcher->dispatch(
      SecurityExtraEvents::INTERACTIVE_LOGOUT, 
      new InteractiveLogoutEvent($request, $response, $token) 
     ); 
    } 
} 

添加一些服務配置(或使用自動裝配):

Namespace\Bridge\Symfony\Security\Handler\DispatchingLogoutHandler: 
    class: 'Namespace\Bridge\Symfony\Security\Handler\DispatchingLogoutHandler' 
    arguments: 
     - '@event_dispatcher' 

活動類

namespace Namespace\Bridge\Symfony; 

final class SecurityExtraEvents 
{ 
    /** 
    * @Event("\Namespace\Bridge\Symfony\Security\Event\Logout\InteractiveLogoutEvent") 
    */ 
    const INTERACTIVE_LOGOUT = 'security.interactive_logout'; 
} 

事件本身:

final class InteractiveLogoutEvent extends Event 
{ 
    /** 
    * @var Request 
    */ 
    protected $request; 

    /** 
    * @var Response 
    */ 
    protected $response; 

    /** 
    * @var TokenInterface 
    */ 
    protected $token; 

    /** 
    * @param Request $request 
    * @param Response $response 
    * @param TokenInterface $token 
    */ 
    public function __construct(Request $request, Response $response, TokenInterface $token) 
    { 
     $this->request = $request; 
     $this->response = $response; 
     $this->token = $token; 
    } 

    /** 
    * @return TokenInterface 
    */ 
    public function getToken() 
    { 
     return $this->token; 
    } 

    /** 
    * @return TokenInterface 
    */ 
    public function getRequest() 
    { 
     return $this->token; 
    } 

    /** 
    * @return Response 
    */ 
    public function getResponse() 
    { 
     return $this->response; 
    } 

    /** 
    * @return string 
    */ 
    public function getName() 
    { 
     return SecurityExtraEvents::INTERACTIVE_LOGOUT; 
    } 
} 

與認購人:

class UserEventSubscriber implements EventSubscriberInterface 
{ 
    /** @var LoggerInterface */ 
    protected $logger; 

    /** @param LoggerInterface $logger */ 
    public function __construct(LoggerInterface $logger) 
    { 
     // inject the session here 
     $this->logger = $logger; 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public static function getSubscribedEvents() 
    { 
     return array(
      SecurityExtraEvents::INTERACTIVE_LOGOUT => 'onInteractiveLogout', 
     ); 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function onInteractiveLogout(InteractiveLogoutEvent $event) 
    { 

     $user = $event->getToken()->getUser(); 

     // save the username in the session here 

     $this->logger->info(
      'A User has logged out.', 
      array(
       'event' => SecurityExtraEvents::INTERACTIVE_LOGOUT, 
       'user' => array(
        'id' => $user->getId(), 
        'email' => $user->getEmail(), 
       ) 
      ) 
     ); 
    } 
} 

kernel.event_subscriber

Namespace\EventSubscriber\UserEventSubscriber: 
    class: 'Namespace\EventSubscriber\UserEventSubscriber' 
    arguments: ['@monolog.logger.user'] 
    tags: 
     - { name: 'kernel.event_subscriber' } 

易呵呵標記它允許用戶?一個有點骯髒的解決方案是創建一個請求偵聽器,將用戶名保存在每個請求的session-flashbag中,以便您可以從註銷頁面模板中的用戶名中獲取該用戶名。

相關問題