2016-05-09 7 views
1

В нашем проекте используется FOSUserBundle с Symfony 2.5. Нам нужно добавить пользовательские данные в сеанс пользователя после входа в систему, который находится в базе данных и является динамическим, но должен быть доступен во всех шаблонах и везде в приложении.Symfony 2.5 с FosUserBundle: добавление данных на глобальную сессию после входа в систему

Я думаю о перекрывая LoginManager.php класс от /пользователя расслоении/Безопасность, но я тоже не совсем уверен, что это самый лучший вариант.

Похоже, что метод logInUser() - это то место, где можно добавить наше пользовательское изменение, учитывая, что оно фактически устанавливает токен, но опять же, если есть более разумный способ сделать это, я обязательно пойду с ним.

+0

почему бы вид даже хотят знать о глобальной переменной, как $ _SESSION? –

+0

Ну, само представление не было бы, вы правы. Но диспетчер, который его управляет, нуждается в данных. Все контроллеры должны иметь доступ к этим глобальным данным. –

+0

[http://stackoverflow.com/questions/7647602](http://stackoverflow.com/questions/7647602/symfony-2-0-3-global-template-variable?rq=1) может быть полезно –

ответ

5

Вы можете добавить интерактивный регистратор входа в систему безопасности, и в этом слушателе вы получите доступ к токену входа, который хранится в сеансе. Этот токен наследует Symfony \ Component \ Security \ Core \ Authentication \ Token \ AbstractToken, поэтому он имеет методы «setAttribute ($ name, $ value)» и «setAttributes (атрибуты массива $)». Баспически все, что вы установили в это свойство, должно храниться в сеансе рядом с пользователем и токеном.

Просто будьте осторожны с тем, что это сериализовано и убедитесь, что вы храните объекты для реализации метода serialize/unserialize, если это необходимо, чтобы не иметь круглых эталонных проблем.

Я рекомендовал этот подход, поскольку он, кажется, в соответствии с вашими требованиями:

  • маркер уже хранится в сессии Symfony
  • маркер уже доступен в любой контроллер через услугу «security.context» находится в контейнере,
  • маркер уже доступен в веточке с помощью кода {{app.security.getToken()}}

Для получения дополнительной информации о проверке подлинности События проверяют поваренную книгу symfony: http://symfony.com/doc/current/components/security/authentication.html#authentication-events

Также вы можете использовать следующий код в качестве ориентира.

В услуги YML

security.interactive_login.listener: 
     class: %security.interactive_login.listener.class% 
     arguments: ['@security.context', '@session'] 
     tags: 
      - { name: kernel.event_listener, event: security.interactive_login, method: onSecurityInteractiveLogin } 

В прослушивателе

use Symfony\Component\Security\Core\SecurityContextInterface; 
use Symfony\Component\HttpFoundation\Session\Session; 
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; 

class SecurityListener 
{ 

    public function __construct(SecurityContextInterface $security, Session $session) 
    { 
     $this->security = $security; 
     $this->session = $session; 
    } 

    public function onSecurityInteractiveLogin(InteractiveLoginEvent $event) 
    { 
     $token = $event->getAuthenticationToken(); 
     $token->setAttribute('key','some stuff i want later'); 
    } 

} 

Надежда это помогает,

Александр Cosoi

+0

Возможно, я не добавляю его правильно в службу, но я не могу заставить его работать. Я добавил SecurityListener точно так же, как вы его описали. Затем в файле services.xml я добавляю следующее: ' ', но, похоже, слушатель никогда не включается в поток. –

+0

А, по-видимому, я пропустил оба аргумента security.context и session. ! –

+0

Извините за отложенный ответ, но похоже, что вы это поняли. Удачи вам в вашем проекте. –