Symfony:自定义ExceptionController

时间:2016-11-06 19:50:51

标签: symfony exception

正在研究symfony2.8应用程序,并且我试图覆盖exceptionController的showAction,一切正常,除非我无法获取当前登录用户,security.token_storage始终返回null。 security.yaml:

security:
    encoders:
       FOS\UserBundle\Model\UserInterface: bcrypt
role_hierarchy:
    ROLE_ADMIN:       ROLE_USER
    ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
    fos_userbundle:
         id: fos_user.user_provider.username_email
firewalls:
    dev:
        pattern: ^/(_(profiler|wdt)|css|images|js)/
        security: false
    main:
        pattern: ^/
        form_login: 
            provider: fos_userbundle
            csrf_provider: security.csrf.token_manager
            check_path: fos_user_security_check
            login_path: fos_user_security_login
            default_target_path: default_security_target
            use_referer: true
        logout:
            path: fos_user_security_logout
            target: default_security_target         
        anonymous: true  
        remember_me:
            key: "%secret%"
            lifetime: 604800 
            path: /
access_control:
    - { path: ^/login, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/admin, role: ROLE_ADMIN } 

并在配置中我将控制器声明为服务块下的服务:twig.controller.exception: class: %twig.controller.exception.class% arguments: ["@twig",%kernel.debug%,"@security.token_storage"] 这是我的控制器:

namespace test\testBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference;
use Symfony\Component\HttpKernel\Exception\FlattenException;
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\TwigBundle\Controller\ExceptionController as baseController;
use FOS\UserBundle\Model\UserInterface;

 class ExceptionController extends baseController
 {
   private $tokenStorage;

public function __construct(\Twig_Environment $twig,$debug,TokenStorage $tokenStorage)
{
    parent::__construct($twig,$debug);
    $this->tokenStorage= $tokenStorage;
}
/**
 * Converts an Exception to a Response.
 *
 * @param Request              $request   The request
 * @param FlattenException     $exception A FlattenException instance
 * @param DebugLoggerInterface $logger    A DebugLoggerInterface instance
 * @param string               $_format   The format to use for rendering (html, xml, ...)
 *
 * @return Response
 *
 * @throws \InvalidArgumentException When the exception template does not exist
 */
public function showAction(Request $request, FlattenException $exception, DebugLoggerInterface $logger = null, $_format = 'html')
{
    /*** $this->securityContext is a pitfall never use it here recommended by the documentation
        $user = $this->tokenStorage->getToken()->getUser();//$this->tokenStorage->getToken() is always null

    if (!is_object($user) || !$user instanceof UserInterface) {
        $user=null;
    }

    $currentContent = $this->getAndCleanOutputBuffering($request->headers->get('X-Php-Ob-Level', -1));
    $code = $exception->getStatusCode();
        return new Response($this->twig->render(
            $this->findTemplate($request, $_format, $code, $this->debug),
            array(
                'status_code'    => $code,
                'status_text'    => isset(Response::$statusTexts[$code]) ? Response::$statusTexts[$code] : '',
                'exception'      => $exception,
                'logger'         => $logger,
                'currentContent' => $currentContent
            )
        ));
}
}

请给我任何建议!

1 个答案:

答案 0 :(得分:1)

我将原来的ExceptionController课程与您的课程进行了比较,并且tokenStorage周围存在细微差异。因此,我没有看到很多攻击TwigBundle只是为了拦截异常并提供Response

为此目的,有一个事件调用KERNEL_EXCEPTION可以收听,如果需要,可以将Response与您自己交换。页面Events and Event Listeners描述了如何。

所以,基本上:

  1. 创建您自己的服务并注入TokenStorage
  2. 使用kernel.exception
  3. 标记
  4. 在您的服务中,根据需要决定您要做什么并放置:

    $event->setResponse($myNewResponse);
    
  5. 这应该可以解决问题。希望这会有所帮助...