2016-04-25 11 views
1

私は本当に変わった状況に遭遇しています。ROLE_ADMINのユーザーは、名前を変更するとすぐにログアウトします。何も変更して保存ボタンを押してもログアウトしても。私がROLE_USERに直接ユーザーの役割を変更した場合、同じコードが正常に動作し、ユーザーはログアウトされません。 Symfony - ユーザーが名前を変更してもログアウトする

は、プロファイル更新の世話をするコントローラである

/** 
    * @Route("/profile", name="profile") 
    */ 
    public function profileAction(Request $request) 
    { 

     $em = $this->getDoctrine()->getManager(); 

     $userInfo = $this->getUser(); 

     //create the form object 
     $profileForm = $this->createForm(UserType::class, $userInfo); 
     $profileForm->handleRequest($request); 


     //check data validity 
     if($profileForm->isValid()){ 
      $em->persist($userInfo); 
      $em->flush(); 
      $this->get('session')->getFlashBag()->add(
       'success', 
       'Your profile information has been updated' 
      ); 

      return $this->render('AppBundle:admin/user:admin-edit.html.twig',array(
       'edit_form' => $profileForm->createView() 
      )); 
     } 


     // render registration form 
     return $this->render('AppBundle:admin/user:admin-edit.html.twig',array(
      'edit_form' => $profileForm->createView() 
     )); 
    } 

} 

これは私のsecurity.yml

security: 
    encoders: 
     # Our user class and the algorithm we'll use to encode passwords 
     # http://symfony.com/doc/current/book/security.html#encoding-the-user-s-password 
     AppBundle\Entity\User: bcrypt 

    providers: 
     # Simple example of loading users via Doctrine 
     # To load users from somewhere else: http://symfony.com/doc/current/cookbook/security/custom_provider.html 
     database_users: 
      entity: { class: AppBundle:User, property: username } 

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

     main: 
      http_basic: ~ 
      anonymous: ~ 
      logout: ~ 
      guard: 
       authenticators: 
        - app.form_login_authenticator 
        - app.facebook_authenticator 
       # by default, use the start() function from FormLoginAuthenticator 
       entry_point: app.form_login_authenticator 
    access_control: 
     - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } 
     - { path: ^/admin/, roles: ROLE_ADMIN } 
     - { path: ^/user, roles: ROLE_USER } 

UPDATEある1

これは私のUserType

です

これは、これは私がこれを引き起こしている可能性があり、本当に無知だ。この時点でAddDepartmentDegreeCourseFieldSubscriber

namespace AppBundle\Form\EventListener; 


use AppBundle\Entity\Degree; 
use AppBundle\Entity\Department; 
use Doctrine\ORM\EntityManager; 
use Symfony\Bridge\Doctrine\Form\Type\EntityType; 
use Symfony\Component\Form\Extension\Core\Type\TextType; 
use Symfony\Component\Form\FormEvent; 
use Symfony\Component\Form\FormEvents; 
use Symfony\Component\EventDispatcher\EventSubscriberInterface; 
use Symfony\Component\Form\FormInterface; 

class AddDepartmentDegreeCourseFieldSubscriber implements EventSubscriberInterface 
{ 

    protected $em; 


    function __construct(EntityManager $em) 
    { 
     $this->em = $em; 
    } 

    public static function getSubscribedEvents() 
    { 
     // Tells the dispatcher that you want to listen on the form.pre_set_data 
     // event and that the preSetData method should be called. 
     return array(
      FormEvents::PRE_SET_DATA => 'onPreSetData', 
      FormEvents::PRE_SUBMIT => 'onPreSubmit' 
     ); 
    } 
    protected function addElements(FormInterface $form, Department $departments = null, Degree $degree = null) 
    { 

     // Add the department element 
     $form->add('department', EntityType::class, array(
       'data' => $departments, 
       'placeholder' => 'provide_department', 
       'class' => 'AppBundle\Entity\Department') 
     ); 
     // Degree are empty, unless we actually supplied a department 
     $degree = array(); 
     if ($departments) { 
      // Fetch the courses from specified degree 
      $repo = $this->em->getRepository('AppBundle:Degree'); 
      $degree = $repo->findByDepartment($departments, array('name' => 'asc')); 
     } 


     // Add the province element 
     $form->add('degree', EntityType::class, array(
       'placeholder' => 'provide_degree', 
       'class' => 'AppBundle\Entity\Degree', 
       'choices' => $degree) 
     ); 
     // Cities are empty, unless we actually supplied a province 
     $courses = array(); 
     if ($degree) { 
      // Fetch the cities from specified province 
      $repo = $this->em->getRepository('AppBundle:Course'); 
      $courses = $repo->findByDegree($degree, array('name' => 'asc')); 
     } 
     // Add the Course element 
     $form->add('course', EntityType::class, array(
      'class' => 'AppBundle\Entity\Course', 
      'choices' => $courses, 
     )); 

    } 
    function onPreSubmit(FormEvent $event) { 

     $form = $event->getForm(); 
     $data = $event->getData(); 
     if (isset($data['degree'])) { 

      // Note that the data is not yet hydrated into the entity. 
      $degree = $this->em->getRepository('AppBundle:Degree')->find($data['degree']); 
      $department = $this->em->getRepository('AppBundle:Department')->find($data['department']); 
      $this->addElements($form, $department, $degree); 
     } 
    } 
    function onPreSetData(FormEvent $event) { 
     //echo "before submit";die; 
     $user = $event->getData(); 
     $form = $event->getForm(); 



     if($user){ 
      //if the selected user has role_user only then display the following fields in edit profile view 
      if (in_array("ROLE_USER", $user->getRoles())) { 
       $degree = (!empty($user) && !empty($user->getCourse())) ? $user->getCourse()->getDegree() : null; 
       $departments = (!empty($user) && !empty($user->getCourse())) ? $user->getCourse()->getDegree()->getDepartment() : null; 
       $this->addElements($form, $departments, $degree); 
      } 

     } 

    } 
} 

である私のAddProfileFieldSubscriber

namespace AppBundle\Form\EventListener; 


use Symfony\Bridge\Doctrine\Form\Type\EntityType; 
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; 
use Symfony\Component\Form\Extension\Core\Type\EmailType; 
use Symfony\Component\Form\Extension\Core\Type\FileType; 
use Symfony\Component\Form\Extension\Core\Type\PasswordType; 
use Symfony\Component\Form\Extension\Core\Type\TextType; 
use Symfony\Component\Form\FormEvent; 
use Symfony\Component\Form\FormEvents; 
use Symfony\Component\EventDispatcher\EventSubscriberInterface; 
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; 
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker; 
use Symfony\Component\Validator\Constraints\NotBlank; 


class AddProfileFieldSubscriber implements EventSubscriberInterface 
{ 
    protected $authorizationChecker; 


    function __construct(AuthorizationChecker $authorizationChecker) 
    { 
     $this->authorizationChecker = $authorizationChecker; 
    } 

    public static function getSubscribedEvents() 
    { 
     // Tells the dispatcher that you want to listen on the form.pre_set_data 
     // event and that the preSetData method should be called. 
     return array(FormEvents::PRE_SET_DATA => 'preSetData'); 
    } 

    public function preSetData(FormEvent $event) 
    { 


     $user = $event->getData(); 
     $form = $event->getForm(); 




     if($user){ 
      $form->add('firstName', TextType::class); 
      $form->add('lastName', TextType::class); 
      $form->add('password', PasswordType::class, array(
       'mapped' => false 
      )); 
      $form->add('profileImage', FileType::class, array(
       'data_class' => null 
      )); 
      if (in_array("ROLE_USER", $user->getRoles())) { 
       $form->add('contactNumber', TextType::class); 

       $form->add('gender', ChoiceType::class, array(
        'choices' => array(
         'Male' => 'm', 
         'Female' => 'f' 
        ), 
        'placeholder' => 'provide_gender' 
       )); 
       $form->add('college', EntityType::class, array(
         'placeholder' => 'provide_college', 
         'class' => 'AppBundle\Entity\College') 
       ); 
       $form->add('interest', EntityType::class, array(
         'class' => 'AppBundle\Entity\Interest', 
         'multiple' => true, 
         'expanded' => false, 
         'by_reference' => false, 
        ) 
       ); 

      } 

      if($this->authorizationChecker->isGranted('ROLE_ADMIN') ) { 

       $form->add('isActive', ChoiceType::class, array(
        'choices' => array(
         'account_active' => '1', 
         'account_inactive' => '0' 
        ), 
        'placeholder' => 'provide_status' 
       )); 
      } 

     } 
     //if the selected user has role_user only then display the following fields in edit profile view 
     else { 
      $form->add('username', EmailType::class); 
      $form->add('password', PasswordType::class, array(
       'constraints' => array(new NotBlank(array(
         'message' => 'user.password.not_blank' 
        ) 
       ),), 
      )); 
     } 
    } 
} 

で、私は本当にここに任意の助けを感謝します...

答えて

0

あなたが提供したものにはかなりの問題があります。あなたが見ている行動に貢献する要素があります。

セキュリティルールのsecurity.ymlで

、あなたはこのラインを持っている:ROLE_ADMINなしの任意の使用は、彼らがこれにアクセスする場合、ログイン画面に戻って撃たしようとしていることを意味し

- { path: ^/admin/, roles: ROLE_ADMIN } 

パターン。

一方、あなたのコントローラでは、あなたは常に管理基づいてルートに戻って、ユーザを向けるいる:意味

/* 
* @Route("admin/profile", name="admin_profile") 
*/ 

は、関係なく、彼らが何をすべきか、彼らは常に管理パターンに送信されませんしています。これは、彼らの役割が変わった場合、ファイアウォールによって蹴られることを意味します。お使いのコントローラで

コントローラ

あなたは罰金、にformTypeにユーザエンティティを結合しています。しかし、あなたがコーディングしている方法は、この仕組みがどういうものか理解できていないことを意味します。

handleRequestに電話すると、Symfonyはフォームからデータを取り出し(送信済みの場合)、それを渡したエンティティとマージします。これは、オブジェクト上でセッターを呼び出す必要がないことを意味しています。すでにすべてのことが行われています。

あなたUserエンティティで持っている必要がありますどのような

Userエンティティは、PlainPasswordフィールド、およびPasswordフィールドです。フォームはPlainPasswordフィールドにのみマップされ、コントローラーではPlainPasswordの値をエンコードしてエンティティのPasswordフィールドに設定し、の値をクリアする(保存したくない)ことを確認します。カスタムユーザエンティティにUserInterface(これが必要)を実装した場合は、eraseCredentialsというメソッドが必要です。これがこれです。 Here is an example。 、私も示唆している何

if($profileForm->isValid()){ 
     // $userInfo is populated by handleRequest 
     if ($userInfo->getPlainPassword()) { 
      // do your encoding/erasing credentials here 
     } 
     // ... 

} 

あなたが書いていることである:

これの結末は、あなたが何か、のように言う、新しいパスワードの入力をチェックしているとき、あなただけのこの操作を行う必要があるということです適切なUserManagerこれらの事のほとんどを処理するクラス。これは物事を集中化し、デバッグを容易にします。 Heres an example

あなたは、このような私が例に書かれてきたようなものを使用している場合、それはまた、あなたがユーザー情報を更新したい場合、あなただけの$userManager->updateUser($user)を呼び出すために、それはあなたのためのすべてのロバの仕事をやる必要があることを意味。

+0

'security.yml'に関して'それは 'admin'で始まるパスにアクセスするために' ROLE_ADMIN'を持つ必要がありますので、設定がうまくいけば、あなたはパスワードについて何を言っているのですか?そのようにしてください。しかし、あなたが提案していることは問題を解決しません。もし私が 'ROLE_USER'がコントローラ内部の同じコードを使ってアクセスできるプロファイルルートを作成したとします。そのプロファイルを完全にうまく更新することができるこの 'ROLE_ADMIN'のみですが、ログアウトすると...なぜログアウトしているのか理解できません。 – Saadia

+0

私は質問を更新しました。コントローラー内のすべてを削除し、計画してシンプルにしておくと、このコードは 'ROLE_USER'でも動作しますが、データを保存した後に' ROLE_ADMIN'をログに記録します。 – Saadia

+0

ROLE_ADMINが確実に保存されていますか?フォームタイプコードを追加できますか? – DevDonkey