2016-11-08 1 views
0

У меня проблема с FOSUserBundle.FatalErrorException в RedirectionListener.php строка 46: Ошибка: вызов функции-члена getUser() для не-объекта

У меня есть переназначения слушателя, чтобы запретить пользователям использовать приложение без входа в систему, вот код:

class RedirectionListener 
{ 
    /** 
    * RedirectionListener constructor. 
    * @param ContainerInterface $container 
    * @throws \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException 
    * @throws \Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException 
    */ 
    public function __construct(ContainerInterface $container) 
    { 
     $this->router = $container->get('router'); 
     $this->securityTokenStorage = $container->get('security.token_storage'); 
    } 

    /** 
    * @param GetResponseEvent $event 
    * @throws \InvalidArgumentException 
    */ 
    public function onKernelRequest(GetResponseEvent $event){ 

    $route = $event->getRequest()->attributes->get('_route'); 

    if($route !== 'fos_user_security_login' && 
     $route !== 'fos_user_resetting_reset' && 
     $route !== 'fos_user_resetting_request' && 
     $route !== 'fos_user_resetting_send_email' && 
     $route !== 'fos_user_resetting_check_email' && 
     $route !== 'fos_user_change_password' && 
     !is_object($this->securityTokenStorage->getToken()->getUser())) //this is line 46 
     { 
     $event->setResponse(new RedirectResponse($this->router->generate('fos_user_security_login'))); 
     } 
    } 
} 

Это моя служба:

services: 
redirectonListener: 
    class: Projects\ProjectsBundle\Listener\RedirectionListener 
    arguments: ['@service_container'] 
    tags: 
     - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest } 

А вот мои настройки брандмауэра из FOSUserBundle Docs:

firewalls: 
    # disables authentication for assets and the profiler, adapt it according to your needs 
    dev: 
     pattern: ^/(_(profiler|wdt)|css|images|js)/ 
     security: false 

    main: 
     pattern: ^/ 
     form_login: 
      provider: fos_userbundle 
      csrf_token_generator: security.csrf.token_manager 
      # if you are using Symfony < 2.8, use the following config instead: 
      # csrf_provider: form.csrf_provider 

     logout:  true 
     anonymous: true 

Я использую версию Symfony 2.8. Может кто поможет!

+0

В конструкторе: var_dump ($ container-> get ('security.token_storage')); что говорит? – Deep

+0

Я мог ошибаться, но разве вы не можете это проверить? if ($ this-> get ('security.authorization_checker') -> isGranted ('IS_AUTHENTICATED_FULLY') === false) – Thomas

+0

@Deep вот результат var_dump: 'object (Symfony \ Component \ Security \ Core \ Authentication \ Token \ Storage \ TokenStorage) # 264 (1) {["токен": "Symfony \ Component \ Security \ Core \ Authentication \ Token \ Storage \ TokenStorage": private] => NULL} ' –

ответ

2

Вы пытались установить access_control в своем security.yml?

Например:

security: 
    #[...] 

    access_control: 
     - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY } 
     - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY } 
     - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY } 
     # and so on, until: 
     - { path: ^/restricted, role: ROLE_USER } 
     # or: 
     - { path: ^/*, role: IS_AUTHENTICATED_ANONYMOUSLY } 

Edit: Не забудьте очистить кэш после изменения.

+0

спасибо, я изменил мой security.yml файл следующим образом: 'access_control: - {путь: ^/логин $, роль: IS_AUTHENTICATED_ANONYMOUSLY} - {путь: ^/регистрация, роль: IS_AUTHENTICATED_ANONYMOUSLY} - {путь: ^/reset, роль: IS_AUTHENTICATED_ANONYMOUSLY} - {путь: ^/admin /, role: ROLE_ADMIN} - {путь: ^/*, role: ROLE_USER} 'и он работал, даже не нуждаясь в прослушивателе перенаправления. –

+0

Приветствую вас, рад, что смогу помочь :) – Dennis

0

Я просто даю вам пример, чтобы вы могли его модифицировать в соответствии с вашими потребностями. Помимо способа прослушивания, вы должны изучить подход security.yml в FOS. Существует много примеров. Например, найдите access_control в http://www.inanzzz.com/, который даст вам 6 примеров для изучения.

Примечание: никогда не вставляйте весь контейнер в качестве параметра обслуживания!

Несколько примеров.

ОБСЛУЖИВАНИЕ

services: 
    application_frontend.event_listener.order_create: 
     class: Application\FrontendBundle\EventListener\OrderCreateListener 
     arguments: 
      - @router 
     tags: 
      - { name: kernel.event_listener, event: kernel.controller, method: onKernelController } 

СЛУШАТЕЛЬ

namespace Application\FrontendBundle\EventListener; 

use Application\FrontendBundle\Controller\OrderController; 
use Symfony\Component\HttpKernel\Event\FilterControllerEvent; 
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; 
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; 
use Symfony\Component\Routing\RouterInterface; 

class OrderCreateListener 
{ 
    private $router; 
    private $redirectRoute = 'fos_user_security_login'; 
    private $invalidRoutes = ['fos_user_security_login', '...', '...']; 

    public function __construct(
     RouterInterface $router 
    ) { 
     $this->router = $router; 
    } 

    public function onKernelController(FilterControllerEvent $event) 
    { 
     $controller = $event->getController(); 
     if (!is_array($controller)) { 
      return; 
     } 

     if (
      $event->isMasterRequest() && // If it is user request 
      $controller[0] instanceof OrderController && // Change it to your controller 
      $this->isValidRoute($event) !== false 
     ) { 
      return; 
     } 

     $url = $this->router->generate($this->redirectRoute); 
     $response = new RedirectResponse($url); 
     $event->setResponse($response); 
    } 

    private function isCreateCarMethod(FilterControllerEvent $event) 
    { 
     $currentRoute = $event->getRequest()->attributes->get('_route'); 
     if (in_array(currentRoute, $this->invalidRoutes)) { 
      return false; 
     } 
    } 
} 
+0

Спасибо за ваш ответ, я считаю, что больше подходит для 'access_control' в файле' security.yml'. –

+0

Хорошо, что вы его решили. Поскольку я также предложил метод access_control, это способ сделать это. – BentCoder

Смежные вопросы