Symfony2设置用户角色默认用户和角色文件

Jan*_*ník 0 php symfony doctrine-orm

我将用户角色存储到数据库时遇到问题.我使用的是原始文件:http://symfony.com/doc/current/book/security.html

在这里:http://symfony.com/doc/current/cookbook/security/entity_provider.html

登录注销正在运行.我可以将用户保存到数据库中,但我不知道如何保存他的角色.是否有可能使用这些文件,或者我还需要再做一个单独服务的文件?我不想使用FOSUser Bundle ...谢谢你的回答.这是链接:

AccountController http://pastebin.com/ycrLyUcg

注册 http://pastebin.com/Q7se6pnF

RegistrationType http://pastebin.com/926tu0hj

用户 http://pastebin.com/aNdQr46C 角色 http://pastebin.com/cg7QTk59 UserRepository http://pastebin.com/LHPuy4We

非常感谢您的回答

编辑10.11.2013 23:00:

编辑11.11.2013 15:20

Sea*_*inn 8

在您的AccountController createAction方法中,您实际上从未Role向用户分配过; 您必须首先设置它,然后才能将其用作身份验证过程的一部分.这样的事情应该坚持Role给定你的上述模型.

if ($registrationForm->isValid()) {
    ...
    $role = new Role();
    $role->setName('User');
    $role->setRole('ROLE_USER');

    $roles = new \Doctrine\Common\Collections\ArrayCollection;
    $roles->add($role);

    $user->setRoles($roles);
    ...
}
Run Code Online (Sandbox Code Playgroud)

另外,我将重新考虑其具有的需求@ManyToMany之间的关系,用户角色,@ManyToOne可能就足够了这里; 无论您是否希望坚持使用任何类型的关联映射,您可能需要确保在持久保存User类时相关角色也会保留.要做到这一点,您可能需要cascade向您的指令添加一条指令User类,如下所示:

class User implements AdvancedUserInterface, \Serializable
{
    ...

    /**
     * @ORM\ManyToMany(targetEntity="Role", inversedBy="users", cascade={"all"})
     */
    private $roles;

    ...
}
Run Code Online (Sandbox Code Playgroud)

默认UserSymfony\Component\Security\Core\User也使用其用户对象的角色集合,因此一旦您拥有角色,您就可以只使用现有的UsernameAuthenticationProvider,希望一切都能正常工作.如果不是,您可能必须自定义身份验证提供程序.

请注意,在上面我们明确地$roles使用setRoles()方法分配属性; 这是因为返回类型getRoles()不是ArrayCollection,而是原语array.如果你希望一切都"正常工作"Symfony现有的身份验证提供程序getRoles()返回原始数组是正确的,据我所知.


对同一问题的新观点(11/10/2013):

" 我按你写的那样做了,但它试图写入acme_roles表,我保存角色类型 - 管理员,用户....但我想将用户的角色保存到user_roles表中 - 我保存用户ID和角色ID "

鉴于您在聊天中的扩展注释中表达了您想要的内容,我的方法是使用三个实体/表来模拟您的用户与角色之间的关系.这显然只是解决问题的一种方法.

你的表是:acme_users(User实体), acme_roles(Role实体),和acme_user_roles(UserRole实体).

  • User不会直接与你的Role对象建立多对多关系,而是你可以在a 和a 之间建立一对多的关系.UserUserRole类类.
  • 关联类UserRole(或者你称之为的任何关系)需要一个主键(id)和两个多对一关系:一个用于一个User,一个用于Role.
  • 没有必要在Role类和类之间创建反向关系UserRole,因为您的角色与其他实体隔离.
  • 分配之前Role到新创建的User,你需要先了解一下它,一旦你找到它,你可以创建UserRole一个关于你$user$role然后添加到您设定的角色User类.

以上只是概述了如何解决问题; 更详细:

  1. 您的User类应UserRole通过@ORM\OneToMany注释将关系映射到实体,例如:

        /**
         * @ORM\OneToMany(targetEntity="UserRole", mappedBy="user", cascade={"all"})
         */
        private $userRoles;
    
    Run Code Online (Sandbox Code Playgroud)
  2. User,更改您的getRoles()方法以返回与其关联的实际角色UserRoles,类似于:

        /**
         * @inheritDoc
         */
        public function getRoles()
        {
            $roles = array();
            foreach ($this->userRoles as $userRole) {
                $roles[] = $userRole->getRole();
            }
            return $roles;
        }
    
    Run Code Online (Sandbox Code Playgroud)
  3. User课堂上,添加getUserRoles(),setUserRoles()(可能是addUserRole())方法,删除setRoles()

  4. UserRole,你想存储实体引用不ID的(它们会被映射为列ID的任何方式,由于教义),所以只是改变$user_id$role_id$user$role分别,并改变他们的映射(如果你还想要多个角色可分配通过UserRole关联,你需要有一个离散的身份/主键,所以添加$id属性),如下所示:

        /**
         * @ORM\Column(type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;
    
        /** 
         * @ORM\ManyToOne(targetEntity="User", inversedBy="userRoles", cascade={"all"})
         */
        private $user;
    
        /**
         * @ORM\ManyToOne(targetEntity="Role", cascade={"all"})
         */
        private $role;
    
    Run Code Online (Sandbox Code Playgroud)
  5. $usersRole班级中删除所有引用.

  6. AccoundController,查找您要分配的角色(即,如果您要分配ROLE_USER查找正确和相应的角色),并将其分配给您UserRole,然后将您分配UserRole给您User,最后坚持您$user,例如:

    $user = $registration->getUser();
    $user->setSalt($this->generateSalt());
    $user->setIsActive(1);
    
    $factory = $this->get('security.encoder_factory');
    $encoder = $factory->getEncoder($user);
    $password = $encoder->encodePassword($user->getPassword(), $user->getSalt());
    
    $user->setPassword($password);
    
    $role = $this->getDoctrine()
                 ->getRepository('AcmeAccountBundle:Role')
                 ->find(2); // Finds "ROLE_USER"
    $userRole = new UserRole();
    $userRole->setRole($role);
    
    $user->addUserRole($userRole);
    
    $em->persist($user);
    $em->flush();
    
    Run Code Online (Sandbox Code Playgroud)
  7. 确保重新生成模式,最直接的方法是运行:

    $ php app/console doctrine:database:drop --force
    $ php app/console doctrine:database:create
    $ php app/console doctrine:schema:drop --force
    $ php app/console doctrine:schema:create
    $ php app/console doctrine:schema:validate
    
    Run Code Online (Sandbox Code Playgroud)