Symfony为用户定义了不同的角色类

时间:2015-08-29 08:25:31

标签: symfony inheritance doctrine-orm roles

我正在努力让以下事情发挥作用:

  • 我的应用程序中有两个角色,我们说ROLE_USERROLE_SUPERUSER
  • 我的用户使用Doctrine
  • 存储在数据库中
  • 角色为ROLE_USER的用户基于简单的User类,如下所示(为了便于阅读,此处已删除了getters / setter):

的Acme \ MyBundle \实体\ user.php的

namespace Acme\MyBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;

use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;

/**
* @ORM\Entity
* @ORM\Entity(repositoryClass="Acme\MyBundle\Entity\UserRepository")
* @ORM\Table("users")
* @UniqueEntity(
*       fields={"email"},
*       message="email already used"
* )
*/
class User implements UserInterface, \Serializable
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\Column(type="string", length=255, unique=true)
     * @Assert\NotBlank()
     * @Assert\Email()
     */
    protected $email;

    /**
     * @ORM\Column(type="string", length=32)
     */
    private $salt;

    /**
     * @ORM\Column(type="string", length=4096)
     */
    private $password;


    /**
     * @ORM\Column(name="is_active", type="boolean")
     */
    private $isActive;


    public function __construct()
    {
        $this->isActive = true;
        $this->salt = md5(uniqid(null, true));
    }

    /**
    * @inheritDoc
    */
    public function getRoles()
    {
    return array('ROLE_USER','ROLE_SUPERUSER');
    }

}
  • 我有另一个课程SuperUser,它扩展了我的User课程,以提供只有ROLE_SUPERUSER用户需要的更多字段:

的Acme \ MyBundle \实体\ SuperUser.php

namespace Acme\MyBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

use Symfony\Component\Validator\Constraints as Assert;


/**
 * @ORM\Entity
 * @ORM\Table(name="super_users")
 */
class SuperUser extends User
{

    /**
     * @var integer
     */
    protected $id;

    /**
     * @var string
     */
    protected $email;


    /**
     * @ORM\Column(type="string", length=32)
     */
    proteced $avatar;


    /**
     * @ORM\Column(type="string", length=50, unique=true)
     */
    proteced $username;

}

在我的控制器中,我使用$user = $this -> getUser();来获取当前用户。但是这会返回User类的实例,即使用户具有SuperUser角色,也无法访问ROLE_SUPERUSER属性或方法。

例如,我可以这样做:

if($this -> get('security.context') -> isGranted('ROLE_SUPERUSER')) {
    $avatar = $this -> getUser () -> avatar;
}

无论如何能够做到吗?我会说这与学说关系有关,但我真的不知道要改变什么。

顺便说一下,正如您所看到的,我的标准username课程中没有User字段,它只存在于SuperUser中,这是否会导致任何问题,因为身份验证是基于username

的先验

编辑:

我认为我的问题没有明确公开,但这可能是由于我目前的代码,这是错误的。

我没有两个用户表,我只想要一个User类(在DB中有一个users表)。身份验证仅在此类上使用电子邮件和密码进行操作。 现在我有另一个类SuperUser```that provides extra fields to users that have role ROLE_SUPERUSER . But ALL superusers are users and have an entry in users``表。我只是想在有关行上创建左连接,这就是我使用继承的原因(但也许有更好的方法)。

如果我想收到所有电子邮件,我可以申请users表。

如果我想获取所有用户名,因为只有超级用户拥有一个,我可以请求superusers表。

2 个答案:

答案 0 :(得分:2)

我会选择两个具有OneToOne关系的实体(无延伸)

/** @Entity **/
class SuperUser
{
    // ...

    /**
     * @ORM\OneToOne(targetEntity="User", mappedBy="superUser")
     **/
    private $user;

    // ...
}

/** @Entity **/
class User
{
    // ...

    /**
     * @ORM\OneToOne(targetEntity="SuperUser", inversedBy="user")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     **/
    private $superUser;

    // ...
}

否则请查看Inheritance Mapping

答案 1 :(得分:0)

然后您应该有两个用户提供程序,并使用一个主提供程序:

security:
    providers:
        master_provider:
            chain:
                providers: [user, super_user]

        user:
            entity: { class: Acme\MyBundle\Entity\User, property: username }
        super_user:
            entity: { class: Acme\MyBundle\Entity\SuperUser, property: username }

        firewalls:
            main:
                provider: master_provider

http://symfony.com/doc/current/cookbook/security/multiple_user_providers.html