首页 文章

设置角色Symfony 2安全性中的错误

提问于
浏览
1

我正在创建一个用户表单,其中通过表单下拉列表选择角色 . 我的表单和实体看起来像这样

//entity

private $roles;
public function getRoles()
{

    return $this->roles;
}

//form

class RoleType extends AbstractType
{
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'choices' => array(
            'ROLE_USER' => 'ROLE_USER',
            'ROLE_ADMIN' => 'ROLE_ADMIN',
        )
    ));
}

public function getParent()
{
    return 'choice';
}

public function getName()
{
    return 'role';
}


class RegistrationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('username')
        ->add('password', 'repeated', array(
            'type' => 'password',
            'invalid_message' => 'The password fields must match.',
            'options' => array('attr' => array('class' => 'password-field')),
            'required' => true,
            'first_options'  => array('label' => 'Password'),
            'second_options' => array('label' => 'Repeat Password'),
        ))
        //->add('terms', 'checkbox', array(
           // 'property_path' => 'termsAccepted',
       // ))
        ->add('firstname')
        ->add('lastname')
        ->remove('photo')
        ->add('email', 'email')
        ->remove('status')
        ->remove('createdBy')
        ->remove('isActive')
        ->remove('dateCreated')
        ->remove('updatedBy')
        ->remove('dateUpdated')
        //->remove('roles', 'choice', array(
           // 'choices' => array('ROLE_USER' => 'ROLE_USER', 'ROLE_ADMIN' => 'ROLE_ADMIN'),
        //))
        ->add('roles', new RoleType(), array(
            'placeholder' => 'Choose Roles',
        ))
        //->add('terms', 'checkbox', array(
          //  'property_path' => 'termsAccepted',
           // 'attr' => array('class' => 'checkbox'),
       // ))
        ->add('Register', 'submit')
    ;
}

public function getName()
{
    return 'registration';
}

创建一个通过表单下拉列表选择角色的用户时我没有问题 . 问题是,在登录期间,它会抛出错误,必须在数组中,而不是在字符串中

可捕获的致命错误:参数4传递给Symfony \ Component \ Security \ Core \ Authentication \ Token \ UsernamePasswordToken :: __ construct()必须是类型数组,字符串给定,在/ var / www /中调用

我改变了我的用户实体

private $roles = array();
 public function setRoles($roles)
{
    $this->roles = $roles;

    return $this;
}

 public function getRoles()
 {
   return array($this->roles);
 }

用户现在可以成功登录,但在表单中添加其他用户时会引发错误

“array”类型的值无法转换为有效的数组键 .

这只是一个简单的用户包 . 我不想使用另一个第三方软件包,如FOSUsersrBundle.Any想法如何解决这个问题?

更新

在控制器中,我用它来存储到数据库中

public function createAction(Request $request)
{
    $em = $this->getDoctrine()->getManager();

    //$form = $this->createForm(new RegistrationType(), new Registration());
    $form = $this->createForm(new RegistrationType(), new Users());

    $form->handleRequest($request);

    if ($form->isValid()) {
        $registration = new Users();
        $registration = $form->getData();
        $registration->setDateCreated(new \DateTime());
        //$registration->setRoles('ROLE_ADMIN');
        $registration->setPhoto('http://www.gravatar.com/avatar/'.md5(trim($request->get('email'))));
        $pwd=$registration->getPassword();
        $encoder=$this->container->get('security.password_encoder');
        $pwd=$encoder->encodePassword($registration, $pwd);
        $registration->setPassword($pwd);
        $em->persist($registration);
        $em->flush();

        $this->addFlash('danger', 'New User successfully added!');
        return $this->redirect($this->generateUrl('voters_list'));
    } else {
        $this->addFlash('danger', 'Some errors buddy cannot proceed, please check!');
        return $this->render('DuterteBundle:Security:register.html.twig',array(
            'form' => $form->createView())
        );
    }

更新

我的基本映射

Project\Bundle\DuterteBundle\Entity\Users:
type: entity
table: users
repositoryClass: Project\Bundle\DuterteBundle\Repository\UsersRepository
#indexes:
    #role_id_idx:
        #columns:
            #- role_id
id:
    id:
        type: integer
        nullable: false
        unsigned: false
        comment: ''
        id: true
        generator:
            strategy: IDENTITY
fields:
    username:
        type: string
        nullable: false
        length: 50
        fixed: false
        comment: ''
    password:
        type: string
        nullable: false
        length: 32
        fixed: false
        comment: ''
    firstname:
        type: string
        nullable: true
        length: 50
        fixed: false
        comment: ''
    lastname:
        type: string
        nullable: true
        length: 50
        fixed: false
        comment: ''
    photo:
        type: string
        nullable: true
        length: 200
        fixed: false
        comment: ''
    email:
        type: string
        nullable: true
        length: 200
        fixed: false
        comment: ''
    status:
        type: string
        nullable: true
        length: 8
        fixed: false
        comment: ''
    roles:
        type: string
        nullable: true
        length: 100
        fixed: false
        comment: ''

在mysql中,users表包含角色列,其中存储了角色,例如'ROLE_USERS',“ROLE_ADMIN”等 . 从用户实体更改getRoles函数

public function getRoles()
  {
        return array('ROLE_USER'_)
  }

将成功记录用户,但即使在数据库中int,角色总是设置为'ROLE_USERS',用户的角色等同于'ROLE_ADMIN'

1 回答

  • 4

    代码中最大的错误是在 getRoles() 函数中返回数组内的数组:

    private $roles = array();
     public function setRoles($roles)
     {
        $this->roles = $roles;
        return $this;
     }
    
     public function getRoles()
     {
       return array($this->roles);
     }
    

    现在,在您的映射信息中,您将角色视为字符串,这意味着您的用户只使用一个角色,这简化了很多事情:

    我们将更改字段的名称,因为安全组件需要一个数组并使用函数“getRoles()”,因为它继承自UserInterface或AdvancedUserInterfaceClass,但是表单检查对象以防万一已存在数据(您还可以编辑和/或预加载要在表单中显示的数据),在数据库和映射信息中进行等效更改是必要的 .

    //entity
    private $role;
    
    public function setRole($role){
        $this->roles = $role;
        return $this;
    }
    
    public function getRole(){
        return $this->roles;
    }
    
    public function getRoles(){
        return array($this->role);
    }
    

    你不需要将它设置为一个数组,考虑到你将它作为一个字符串保留,安全组件不会注册用户,你这样做 . 为此我们将改变你的formtypes和你的控制器 .

    //formtype
    //I don't know what version you are using, but you dont need a separate formtype to add a choice and neither need to `remove` fields, you just don't `add` them.
    //Remember to change the field in from 'roles' to 'role'
    class RegistrationType extends AbstractType
    {
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('username')
            ->add('password', 'repeated', array(
                'type' => 'password',
                'invalid_message' => 'The password fields must match.',
                'options' => array('attr' => array('class' => 'password-field')),
                'required' => true,
                'first_options'  => array('label' => 'Password'),
                'second_options' => array('label' => 'Repeat Password'),
            ))
            ->add('firstname')
            ->add('lastname')
            ->add('email', 'email')
            ->add('role', 'choice', array(
                'choices' => array('ROLE_USER' => 'User', 'ROLE_ADMIN' => 'Admin'),
            ))
            ->add('Register', 'submit')
        ;
    }
    
    public function configureOptions(OptionsResolver $resolver) {
        $resolver->setDefaults(array(
            'data_class' => 'Project\Bundle\DuterteBundle\Entity\Users' //this is important
        ));
    }
    }
    

    现在你的控制器:

    //Controller
    //Also if you link a form to a entity you dont need the `getData()`
    
    use Project\Bundle\DuterteBundle\Entity\Users;
    
    public function createAction(Request $request)
    {
        $em = $this->getDoctrine()->getManager();
        $user = new Users();
        $form = $this->createForm(new RegistrationType(), $user);
    
        $form->handleRequest($request); //here, every form field that has an equivalent in the entity, fills the entity property instead, that's why you only need to set the role as a string ;)
    
        if ($form->isValid()) {
            $user->setDateCreated(new \DateTime());
            $user->setPhoto('http://www.gravatar.com/avatar/'.md5(trim($request->get('email'))));
            $pwd=$user->getPassword();
            $encoder=$this->container->get('security.password_encoder');
            $pwd=$encoder->encodePassword($user, $user->getPassword());
            $user->setPassword($pwd);
            $em->persist($user);
            $em->flush();
    
            $this->addFlash('danger', 'New User successfully added!');
            return $this->redirect($this->generateUrl('voters_list'));
        } else {
            $this->addFlash('danger', 'Some errors buddy cannot proceed, please check!');
            return $this->render('DuterteBundle:Security:register.html.twig',array(
                'form' => $form->createView())
            );
        }
    }
    

    你可以看到更简单,更简单,更干净 . 安全组件使用 getRoles 将角色加载到应用程序中,是一个数组,因为用户可以获得多个角色,但为此您需要一个不同的模式 .

相关问题