【问题标题】:how to check the user role inside form builder in Symfony2?如何在 Symfony2 的表单生成器中检查用户角色?
【发布时间】:2013-01-13 04:48:03
【问题描述】:

好的,我正在尝试检查用户是否具有特定角色,我做了this

但是,当我这样做时:

public function buildForm(FormBuilder $builder, array $options)
{
    $builder
        ->add('nombre',null,array('label' => 'Usuario'))
        ->add('email')
        ->add('password', 'repeated', array(
            'type' => 'password',
            'invalid_message' => 'Los campos deben coincidir',
            'first_name' => 'password',
            'second_name' => 'confirmar password',
            'options' => array('required' => false)
            ))

        ->add('cliente', 'entity', array(
        'class' => 'ClientesBundle:Cliente',
        'empty_value' => 'Company',            
        'required'    => false,
        'empty_data'  => null)
    **)**
      $user = $this->securityContext->getToken()->getUser();
      **if ($user->getRol() == 'ROLE_SUPER_ADMIN'){**
        ->add('rol') 
        **}**
    ;

}

也试过了:

 **if ($this->securityContext->getToken()->getUser()->getRol() === 'ROLE_SUPER_ADMIN'){**
            ->add('rol') 
            **}**

粗体线(带有 ** 的线)有一个小红线,表示错误,如果... 我该如何解决这个问题?

【问题讨论】:

    标签: symfony formbuilder role


    【解决方案1】:

    您必须从控制器将用户对象传递给表单构建器

    $form = $this->createForm(
        new YourType(), 
        $data, 
        array('user' => $this->getUser())
    );
    

    然后在表单生成器中,您可以从$options 获取它:

    public function buildForm(FormBuilder $builder, array $options)
    {
        $user = $options['user']
    }
    

    别忘了用user 扩展setDefaultOptions() 索引:

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            ...
            'user' => null
        ));
    }
    

    【讨论】:

    • 这就是我一直在寻找的!
    • 对于 SF3 使用:public function configureOptions(OptionsResolver $resolver) 而不是 setDefaultOptions(OptionsResolverInterface $resolver)
    【解决方案2】:

    如果您将表单类型声明为服务,则可以在您的类中注入令牌存储。

    所以你像这样在services.yml 中声明服务:

    my_form:
        class: AppBundle\Services\MyFormType
        public: true
        arguments:  ['@security.token_storage']
    

    还有这样的表单类:

    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
    
    class MyFormType extends AbstractType
    {
        protected $tokenStorage;
    
        public function __construct(TokenStorage $tokenStorage)
        {
            $this->tokenStorage = $tokenStorage;
        }
    
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $user = $this->tokenStorage->getToken()->getUser();
            // Use the user object to build the form
        }
    }
    

    【讨论】:

    • 这是使用 Symfony 的方法!总是使用依赖注入。
    • 在 Symfony 3.4 中,我必须在 services.yml 中添加标签:[form.type]
    【解决方案3】:

    我知道这是一个老问题,但我想提出一个更好的替代方法来检查表单类型中的角色。

    问题

    使用 TokenInterface 和 User 对象的问题是它不检查继承。例如,考虑以下security.yml

    security:
        role_hierarchy:
            ROLE_ADMIN: ROLE_USER
            ROLE_SUPER_ADMIN: ROLE_ADMIN
    

    如果您的用户在其角色中添加了ROLE_SUPER_ADMIN 但未添加ROLE_ADMIN,则如果您使用$user->hasRole('ROLE_ADMIN'),上述解决方案将失败,因为用户没有明确拥有ROLE_ADMIN分配给他们的用户,hasRole() 不检查层次结构。


    解决办法

    请改用AuthorizationCheckerInterface 来访问isGranted() 函数。

    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
    
    class MyFormType extends AbstractType {
    
        protected $auth;
    
        public function __construct(AuthorizationCheckerInterface $auth) {
            $this->auth = $auth;
        }
    
        public function buildForm(FormBuilderInterface $builder, array $options) {
    
            // ...
    
            if($this->auth->isGranted('ROLE_ADMIN')) {
                // Do the thing here
            }
        }
    }
    

    这将尊重security.yml 中定义的任何层次结构。如果我们使用与上面相同的 yml 文件,$auth->isGranted('ROLE_ADMIN') 将返回 true 如果用户将 ROLE_SUPER_ADMIN 分配给他们的个人资料但未分配 ROLE_ADMIN

    【讨论】:

      【解决方案4】:

      我成功地完成了这件事而没有传递给 symfony 3.4 中的服务。我知道我的方法不是最“专业”的,但它很简单而且很有效。

      首先,从您的控制器发送您的 formType 中的用户

      $form = $this->get('form.factory')->create(addPlanExpectedType::class, $business,
                  array('user' => $this->getUser())
              );
      

      其次,恢复角色,并验证“ROLE_AMIN”是否在这个 $roles 数组中

      public function buildForm(FormBuilderInterface $builder, array $options)
          {
      
              $businessId = $options['data']->getId();
      
              $user = $options['user'];
              $roles = $user->getRoles();
      
              $boolAdmin = in_array('ROLE_ADMIN', $roles);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-08
        • 1970-01-01
        • 2019-10-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多