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


Symfony2 set user role default User and Role files

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

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

登录 注销正在工作。我可以将用户保存到数据库中,但我不知道如何保存他的角色。是否可以使用此文件,或者我必须再做一个单独提供此文件的文件?我不想使用FOSUser Bundle... 谢谢你的回答。以下是链接:

帐户控制器 http://pastebin.com/ycrLyUcg

注册 http://pastebin.com/Q7se6pnF

注册类型 http://pastebin.com/926tu0hj

用户 http://pastebin.com/aNdQr46C角色 http://pastebin.com/cg7QTk59用户存储库 http://pastebin.com/LHPuy4We

非常感谢您的回答

编辑 10.11.2013 23:00:

  • http://pastebin.com/DDygxzDN 帐户控制器.php
  • http://pastebin.com/SmSJMm4t 用户.php
  • http://pastebin.com/fEZk7JPa 用户角色.php

编辑11.11.2013 15:20

  • http://pastebin.com/Zu8w7cQ9 角色.php

在 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);
    ...
}

此外,我会重新考虑在用户角色之间建立@ManyToMany关系的要求,@ManyToOne在这里可能就足够了;无论您是否希望坚持任何类型的关联映射,您都可能需要确保在持久化User类时,关联的角色也会持久化。为此,您可能需要向User类添加cascade指令,如下所示:

class User implements AdvancedUserInterface, 'Serializable
{
    ...
    /**
     * @ORM'ManyToMany(targetEntity="Role", inversedBy="users", cascade={"all"})
     */
    private $roles;
    ...
}

Symfony'Component'Security'Core'User 中的默认 User 类也为其用户对象使用角色集合,因此一旦您保留了角色,您就可以只使用现有的 UsernameAuthenticationProvider,希望一切都会正常工作。如果没有,则可能需要自定义身份验证提供程序。

请注意,在上面,我们使用 setRoles() 方法显式分配 $roles 属性;这是因为 getRoles() 的返回类型不是ArrayCollection,而是基元array。如果您希望所有内容都"仅与Symfony现有的身份验证提供程序一起工作"getRoles()据我所知,原始数组是正确的。


重新审视同一问题 (11/10/2013):

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

鉴于您在聊天中的扩展评论中指示您想要的内容,我的方法是使用三个实体/表来建模您的用户与角色关系。这显然只是解决问题的一种方式。

您的表将是:acme_usersUser实体)、acme_rolesRole实体)和acme_user_rolesUserRole实体)。

  • User不会直接与Role对象建立多对多关系,相反,您可以在UserUserRole类之间建立一对多关系。
  • 关联类,UserRole(或任何你称呼它)需要一个主键(id)和两个多对一关系:一个用于User,一个用于Role
  • 没有必要
  • Role类和UserRole之间创建反向关系,因为你的角色与其他实体是隔离的。
  • 在为新创建的User分配Role之前,您需要先查找它,找到它后,您可以使用对$user$role的引用来创建UserRole,然后将其添加到User类上的角色集。

以上只是你如何处理这个问题的粗略概述;更详细地说:

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

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

        /**
         * @inheritDoc
         */
        public function getRoles()
        {
            $roles = array();
            foreach ($this->userRoles as $userRole) {
                $roles[] = $userRole->getRole();
            }
            return $roles;
        }
    
  3. 在类User,添加getUserRoles()setUserRoles()(可能还有addUserRole())方法,删除setRoles()

  4. UserRole 中,您希望存储实体引用而不是 ID(由于 Doctrine,它们将以任何方式在列中映射为 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;
    
  5. Role类中删除对$users的所有引用。

  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();
    
  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
    

所以问题解决了。我使用了本教程中的文件:http://symfony.com/doc/current/cookbook/security/entity_provider.html。比我不得不这样做:

$ PHP 应用程序/控制台 原则:数据库:丢弃 --强制

$ PHP 应用程序/控制台 原则:数据库:创建

$ PHP 应用程序/控制台原则:模式:丢弃 --force

$ PHP 应用程序/控制台 原则:模式:创建

$ PHP 应用程序/控制台原则:模式:验证

谢谢肖恩·奎因