Symfony 4 - 从DB定义自定义用户角色

3 user-roles symfony

我正在学习Symfony 4,我迷失了用户角色,我不知道从哪里开始.因为它将是一个类似于网站的内部网用户不会自己注册,管理员将注册它们并设置角色.管理员还可以动态创建新角色.我想将用户角色存储在数据库中.我有2个实体User和Role.(关系尚未定义,这是正常的)

这是我的User实体:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\UserInterface;

/**
 * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
 * @UniqueEntity(fields="email", message="Email already taken")
 * @UniqueEntity(fields="username", message="Username already taken")
 */
class User implements UserInterface, \Serializable
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\Column(type="integer", unique=true)
     */
    private $id;

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

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

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

    /**
     * @ORM\Column(type="date")
     */
    private $birthdate;

    /**
     * @ORM\Column(type="integer", nullable=true)
     */
    private $roleId;

    /**
     * @ORM\Column(type="string", length=255, nullable=false)
     */
    private $username;

    /**
     * @Assert\NotBlank()
     * @Assert\Length(max=4096)
     */
    private $plainPassword;

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

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

    // GETTERS

    public function getId()
    {
        return $this->id;
    }

    public function getFirstname()
    {
        return $this->firstname;
    }

    public function getLastname()
    {
        return $this->lastname;
    }

    public function getBirthdate()
    {
        return $this->birthdate;
    }

    public function getEmail()
    {
        return $this->email;
    }

    public function getRoleId()
    {
        return $this->roleId;
    }

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

    public function getUsername()
    {
      return $this->username;
    }

    public function getPlainPassword()
    {
        return $this->plainPassword;
    }

    public function getPassword()
    {
      return $this->password;
    }

    public function getSalt()
    {
     return null;
    }

    // SETTERS

    public function setFirstname($firstname)
    {
        $this->firstname = $firstname;
    }

    public function setLastname($lastname)
    {
        $this->lastname = $lastname;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }

    public function setBirthdate($birthdate)
    {
        $this->birthdate = $birthdate;
    }

    public function setRoleId($roleId)
    {
        $this->roleId = $roleId;
    }

    public function setUsername($username)
    {
        $this->username = $username;
    }

    public function setPlainPassword($password)
    {
        $this->plainPassword = $password;
    }


    public function setPassword($password)
    {
        $this->password = $password;
    }

    // FUNCTIONS

    public function serialize()
    {
        return serialize(array(
            $this->id,
            $this->username,
            $this->password,
            // see section on salt below
            // $this->salt,
        ));
    }

    /** @see \Serializable::unserialize() */
    public function unserialize($serialized)
    {
        list (
            $this->id,
            $this->username,
            $this->password,
            // see section on salt below
            // $this->salt
        ) = unserialize($serialized);
    }

    public function eraseCredentials()
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的Role实体:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\RoleRepository")
 */
class Role
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer", unique=true)
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255, nullable=false)
     */
    private $type;

    // GETTERS

    public function getId()
    {
        return $this->id;
    }

    public function getType()
    {
        return $this->type;
    }

    // SETTERS

    public function setType($type): void
    {
        $this->type = $type;
    }
}
Run Code Online (Sandbox Code Playgroud)

这样做是一个好习惯吗?

在Symfony文档中,我们可以随处读取"宏" ROLE_USER,ROLE_ADMIN......它们在哪里定义?我们可以自定义吗?

dbr*_*ann 16

Symfony用于支持具有RoleInterface的角色实体,就像您的用户实现UserInterface一样.决定这是不必要的,因为roles-table通常只包含2个字段(id,name),这意味着我们也可以将角色直接存储在users表中.

因此,如果您想要遵循Symfony最佳实践,您只需在用户中拥有自己的角色,例如:

class User implements UserInterface
{
    /** @Column(type="json") */
    private $roles = [];

    public function getRoles(): array
    {
        return array_unique(array_merge(['ROLE_USER'], $this->roles));
    }

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

    public function resetRoles()
    {
        $this->roles = [];
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您不想将角色存储为JSON编码的字符串,您还可以使用@Column(type="array") */或编写自定义DBAL类型,例如某种EnumType.您可能还希望保护setter免受无效数据的影响或添加验证.

关于文档中使用的角色的第二个问题:Symfony具有某些预定义角色和某些功能的伪角色:

  • IS_AUTHENTICATED_ANONYMOUSLY
  • IS_AUTHENTICATED_REMEMBERED
  • IS_AUTHENTICATED_FULLY
  • ROLE_ALLOWED_TO_SWITCH(用于用户切换)

其他角色喜欢ROLE_USER并且ROLE_ADMIN纯粹是示范性的,您可以根据自己的需要使用它们.您甚至不必使用a开始自己的角色ROLE_(尽管某些安全功能依赖于此约定,除非您进行一些手动更改,否则这些角色将无法正常工作).