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

时间:2013-11-05 16:53:51

标签: 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:

EDIT 11.11.2013 15:20

2 个答案:

答案 0 :(得分: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);
    ...
}

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

class User implements AdvancedUserInterface, \Serializable
{
    ...

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

    ...
}

User中的默认Symfony\Component\Security\Core\User类也为其用户对象使用了一组角色,因此一旦您拥有角色,您就可以只使用现有的{{3}希望一切都能正常运作。如果不是,您可能必须自定义身份验证提供程序。

请注意,在上面我们明确地使用$roles方法分配setRoles()属性;这是因为getRoles()的返回类型不是ArrayCollection,而是原始array。如果您希望所有内容都能与Symfony现有的身份验证提供程序“正常工作”,并且getRoles()返回原始数组是正确的。


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

  

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

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

您的表格为:acme_usersUser实体),acme_rolesRole实体)和acme_user_rolesUserRole实体)

  • 您的UserRole个对象没有直接的多对多关系,而是User对象之间可能存在一对多关系{1}}和UserRole类。
  • 关联类UserRole(或者你称之为的任何关系)需要一个主键(id)和两个多对一关系:一个用于User和一个对于Role
  • 无需在Role类和UserRole之间创建反向关系,因为您的角色与其他实体隔离开来。
  • 在为新创建的Role分配User之前,您需要先查找它,一旦找到它,您就可以创建UserRole并引用您的{{1}然后将{}添加到$user类的角色集。

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

  1. 您的$role课程应通过User注释将关系映射到User实体,例如:

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

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

  4. addUserRole()中,您希望存储实体引用而不是ID(由于Doctrine,它们将以任何方式映射为列中的ID),因此只需更改setRoles()和{{ 1}}分别改为UserRole$user_id并更改其映射(如果您希望通过$role_id关联分配多个角色,则需要具有离散的标识/主键,所以添加$user属性),如下所示:

    $role
  5. UserRole课程中删除对$id的所有引用。

  6. /** * @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; 中,查找您要分配的角色(即,如果您要指定$users查找正确且相应的角色),并将其分配给您的{{ 1}},然后将Role分配给AccoundController,最后保留ROLE_USER,例如:

    UserRole
  7. 确保重新生成架构,最直接的方法是运行:

    UserRole

答案 1 :(得分:1)

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

  

$ 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

谢谢Sean Quinn