getRole() form RoleInterface returns 在 symfony 上为空

getRole() form RoleInterface returns empty on symfony

我在 symfony 上实现 JWT 令牌时遇到了很大的问题。 我已经使用了 JWT 令牌,但我也需要将用户角色添加到令牌信息中。我正在使用监听器 (JWTCreatedListener) 执行此操作:

public function onJWTCreated(JWTCreatedEvent $event)
{
    $request = $this->requestStack->getCurrentRequest();

    $payload       = $event->getData();
    $payload['ip'] = $request->getClientIp();
    $payload['roles'] = $event->getUser()->getRoles();

    $event->setData($payload);
}

我是这样实现的Role.php (AppBundle/Entity/Role.php):

<?php

namespace AppBundle\Entity;

use Symfony\Component\Security\Core\Role\RoleInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Table(name="acme_role")
 * @ORM\Entity()
 */
class Role implements RoleInterface
{
    /**
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id()
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

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

    /**
     * @ORM\Column(name="role", type="string", length=20, unique=true)
     */
    private $role;

    /**
     * @ORM\ManyToMany(targetEntity="User", mappedBy="roles")
     */
    private $users;

    public function __construct()
    {
        $this->users = new ArrayCollection();
    }

    /**
     * @see RoleInterface
     */
    public function getRole()
    {
        return $this->role;
    }

    // ... getters and setters for each property

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     *
     * @return Role
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set role
     *
     * @param string $role
     *
     * @return Role
     */
    public function setRole($role)
    {
        $this->role = $role;

        return $this;
    }

    /**
     * Add user
     *
     * @param \AppBundle\Entity\User $user
     *
     * @return Role
     */
    public function addUser(\AppBundle\Entity\User $user)
    {
        $this->users[] = $user;

        return $this;
    }

    /**
     * Remove user
     *
     * @param \AppBundle\Entity\User $user
     */
    public function removeUser(\AppBundle\Entity\User $user)
    {
        $this->users->removeElement($user);
    }

    /**
     * Get users
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getUsers()
    {
        return $this->users;
    }
}

我的用户 class:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Table(name="users")
 * @ORM\Entity
 */
class User implements AdvancedUserInterface, \Serializable
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

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

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

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

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

    public function __construct($username)
    {
        $this->isActive = true;
        $this->username = $username;
        $this->roles = new ArrayCollection();
    }

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

    public function getSalt()
    {
        return null;
    }

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

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

    public function getRoles()
    {
         return $this->roles->toArray();
    }

    public function eraseCredentials()
    {
    }

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set username
     *
     * @param string $username
     *
     * @return User
     */
    public function setUsername($username)
    {
        $this->username = $username;

        return $this;
    }

    /**
     * Set isActive
     *
     * @param boolean $isActive
     *
     * @return User
     */
    public function setIsActive($isActive)
    {
        $this->isActive = $isActive;

        return $this;
    }

    /**
     * Get isActive
     *
     * @return boolean
     */
    public function getIsActive()
    {
        return $this->isActive;
    }

    /**
     * Add role
     *
     * @param \AppBundle\Entity\Role $role
     *
     * @return User
     */
    public function addRole(\AppBundle\Entity\Role $role)
    {
        $this->roles[] = $role;

        return $this;
    }

    /**
     * Remove role
     *
     * @param \AppBundle\Entity\Role $role
     */
    public function removeRole(\AppBundle\Entity\Role $role)
    {
        $this->roles->removeElement($role);
    }

    public function isAccountNonExpired()
    {
        return true;
    }

    public function isAccountNonLocked()
    {
        return true;
    }

    public function isCredentialsNonExpired()
    {
        return true;
    }

    public function isEnabled()
    {
        return $this->isActive;
    }

    // serialize and unserialize must be updated - see below
    public function serialize()
    {
        return serialize(array(
            // ...
            $this->isActive
        ));
    }
    public function unserialize($serialized)
    {
        list (
            // ...
            $this->isActive
        ) = unserialize($serialized);
    }
}

问题是这个方法 getRole() 总是 returns 空。

这是我的数据库数据:

[users]
    id  username  password                                           is_active
    1  abriceno  y$NW6uNOKJGUQTSXirej4HKOwIa6mWzYqFxzz1ppWQjyp... 1

[acme_role]
id  name    role
1   admin   ROLE_ADMIN

[user_role]
user_id user_role
1        1

此外,我尝试使用 doctrine 从控制器测试中调用数据:

public function indexAction(Request $request)
    {

       $repository = $this->getDoctrine()->getRepository('AppBundle:User');
        $user = $repository->findOneByusername('abriceno');


        $username = $user->getUsername();
        $roles = $user->getRoles();

        $arr = array(
            'username' => $user->getUsername(),
            'password' => $user->getPassword(),
            'roles' => $user->getRoles()
        );
       return new JsonResponse($arr);

这个returns:

{"username":"abriceno","password":"y$NW6uNOKJGUQTSXirej4HKOwIa6mWzYqFxzz1ppWQjypQJLIgUGJ.m","roles":[{}]}

我很绝望...谢谢你能提供给我的所有帮助。

更新 1

如果我这样做 print_r($role) 这将打印一个 huuuuuge 值列表:

array(1) { [0]=> object(AppBundle\Entity\Role)#624 (4) { ["id":"AppBundle\Entity\Role":private]=> int(1) ["name":"AppBundle\Entity\Role":private]=> string(5) "admin" ["role":"AppBundle\Entity\Role":private]=> string(10) "ROLE_ADMIN" ["users":"AppBundle\Entity\Role":private]=> object(Doctrine\ORM\PersistentCollection)#626 (9) { ["snapshot":"Doctrine\ORM\PersistentCollection":private]=> array(0) { } ["owner":"Doctrine\ORM\PersistentCollection":private]=> *RECURSION* 

...并继续...很奇怪!!

似乎连接 table 不直接由学说处理,因此您需要指定学说如何使用 JoinTable 注释映射引用字段(请参阅 default mapping 部分。)

对于您的情况,请尝试修改 User 实体中的 roles relation 定义,如下所示:

/**
 * @ORM\ManyToMany(targetEntity="Role", inversedBy="users")
 * @ORM\JoinTable(name="user_role",
 *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
 *      inverseJoinColumns={@ORM\JoinColumn(name="user_role", referencedColumnName="id")})
 *
 */
private $roles;

希望对您有所帮助

最后我用这段代码解决了这个问题:

        // Work of roles
    $roles = $event->getUser()->getRoles();
    $role_length = count($roles); 
    $role_list = array();
    for ($i=0; $i <$role_length ; $i++) { 
    array_push($role_list,$roles[$i]->getRole());
    }


    $payload       = $event->getData();
    $payload['ip'] = $request->getClientIp();
    $payload['roles'] = $role_list;

问题(我猜)出在 ->getRoles(); 代码上。这 returns Entity\Role class 的数组,而不是角色的数组。

现在转储是:

{
  "token": "eyJhbGciOiJSUzI1NiJ9.....",
  "data": {
    "roles": [
      "ROLE_ADMIN"
    ]
  }
}