silex symfony:getRoles在登录时返回空列表
你好,Silex(和Symfony)专家 我需要通过条令/ORM实现数据库身份验证用户/角色模型 这是我的silex composer设置:silex symfony:getRoles在登录时返回空列表,symfony,orm,doctrine,roles,silex,Symfony,Orm,Doctrine,Roles,Silex,你好,Silex(和Symfony)专家 我需要通过条令/ORM实现数据库身份验证用户/角色模型 这是我的silex composer设置: "require": { "silex/web-profiler": "^2.0", "monolog/monolog": "1.13.*", "symfony/twig-bridge": "^3.2", "symfony/monolog-bridge": "^3.2", "symfony/console": "^3
"require": {
"silex/web-profiler": "^2.0",
"monolog/monolog": "1.13.*",
"symfony/twig-bridge": "^3.2",
"symfony/monolog-bridge": "^3.2",
"symfony/console": "^3.2",
"symfony/yaml": "^3.2",
"symfony/security-bundle": "^3.2",
"doctrine/orm": "^2.5",
"dflydev/doctrine-orm-service-provider": "^2.0",
"symfony/form": "^3.2",
"symfony/validator": "^3.2",
"symfony/config": "^3.2",
"symfony/doctrine-bridge": "^3.2",
"doctrine/migrations": "^1.5"
},
用户可以注册。注册用户可以登录和注销。未注册的访问者具有匿名角色
symfony探查器正在工作,因此我可以查看安全状态(身份验证/授权)。我还跟踪apache日志文件中的php错误
我从这里开始(用户来自数据库,角色作为数组),并尝试扩展它,通过多对多关系从数据库中获取用户角色
有:
class MyUserController (different user actions like user,edit, register,... )
class MyUserManager implements UserProviderInterface (loadUserByUsername, ...)
class MyUserServiceProvider implements ServiceProviderInterface, ControllerProviderInterface, BootableProviderInterface (controller routing and template setting)
ORM实体包括:
User:
/**
* MyUser
*
* @Entity
* @Table(name="myuser")
*/
class MyUser implements UserInterface, \Serializable
{
....
/**
* @ManyToMany(targetEntity="MyRole", inversedBy="users")
*
*/
private $roles;
...
* Constructor.
*
* @param string $email
*/
public function __construct($email)
{
$this->email = $email;
$this->created = time();
$this->salt = base_convert(sha1(uniqid(mt_rand(), true)), 16, 36);
$this->roles = new ArrayCollection();
}
...
/**
*
* @return ArrayCollection list of the user's roles.
*/
public function getRoles()
{
$result = $this->roles->toArray(); // throws error for login:
// $result = $this->roles; // test // thhrows error : null object
dump($this->roles);
// $result = array("ROLE_USER", "ROLE_OTHER"); // static setting and
works for login
return $result;
}
...
}
Roles (implements Roleinterface)
/**
* MyRole
*
* @Entity
* @Table(name="myrole")
*/
class MyRole implements RoleInterface
{
/**
* @var string
* @Column(name="role", type="string", length=20, unique=true)
*/
private $role;
/**
* @ManyToMany(targetEntity="MyUser", mappedBy="roles")
*/
private $users;
...
/*
* methods for RoleInterface
* @return string|null A string representation of the role, or null
*/
public function getRole()
{
$result = $this->role;
return $result;
}
}
当用户注册时,他将获得该会话的角色_userrole,
身份验证和授权正常,并且在中创建了用户
数据库
然后我可以在控制器中为新用户分配新角色(“角色\u test1”、“角色\u test2”),多对多表myuser\u myrole被填充(myuser\u id myrole\u id)。
当我更改角色时,实体管理器会正确更新角色
当我从userController访问用户实体进行操作时,我可以访问分配的角色:
// MyUserController.php
$user = $em->getRepository('MyEntities\MyUser')->find($id);
$roles= $user->getRoles()
$role_length = count($roles);
$role_list = array();
for ($i=0; $i <$role_length ; $i++)
{
array_push($role_list,$roles[$i]->getRole()); // MyRole::getRole() prints out something to screen.
}
printf("<br> role-list:"); dump($role_list);
它抛出:
Argument 4 passed to Symfony\\Component\\Security\\Core\\Authentication\\Token\\UsernamePasswordToken::__construct() must be of the type array, object given,
好吧,也许有道理,因为$roles是一个Doctrine ArrayCollection
roles:
ArrayCollection {#388 ▼
-elements: []
}
当我使用
// MyUser::getRoles()
return $this->roles;
// MyUser::getRoles()
return $this->roles->toArray();
我可以使用用户密码登录,但未通过身份验证(黄色状态)。卸下角色后,我收到一个空数组ArrayCollection
roles:
ArrayCollection {#388 ▼
-elements: []
}
UsernamePasswordToken具有空角色数组
When I use
// MyUser::getRoles()
return array("ROLE_HELLO1", "ROLE_HELLO2"); // static role array with strings
我可以登录并通过以下角色进行身份验证:
角色
array:2 [▼
0 => "ROLE_HELLO1"
1 => "ROLE_HELLO2"
]
对于symfony 2,有一些关于这方面的旧文档(管理数据库中的角色),但在symfony 3中它不起作用
在这里他们使用
//class User
public function getRoles()
{
return $this->groups->toArray();
}
//class Group extends Role (not RoleInterface, old?)
public function getRole()
{
return $this->role;
}
用于用户管理的实际symfony文档没有显示如何使用存储在数据库中的角色
总之:
登录名和用户/角色未按预期工作:
MyUser::getRoles()
- 不通过ORM从数据库接收角色
- 必须为登录返回角色的字符串数组
- 在另一个控制器中传递正确的角色关联
public function getRoles()
{
return $this->roles->map(function (MyRole $role) {
return $role->getRole();
})->toArray();
}
您还应该检查关系是否正确保存在数据库中。
如果MyUser和MyRole之间存在ManyToMany关系,则必须确保该关系保存在两个实体中
//class MyUser
public function addRole(MyRole $role)
{
$this-roles->add($role);
$role->users->add($user);
}
试试这个:
public function getRoles()
{
return $this->roles->map(function (MyRole $role) {
return $role->getRole();
})->toArray();
}
您还应该检查关系是否正确保存在数据库中。
如果MyUser和MyRole之间存在ManyToMany关系,则必须确保该关系保存在两个实体中
//class MyUser
public function addRole(MyRole $role)
{
$this-roles->add($role);
$role->users->add($user);
}
我在这件事上休息了一下,但现在它似乎起作用了。谢谢miikes的addRole()建议 最后我有:MyUser.php:
//Myuser.php
/**
* MyUser
*
* @Entity
* @Table(name="myuser")
*/
class MyUser implements UserInterface, \Serializable //, ObjectManagerAware
{
...
/**
* @ManyToMany(targetEntity="MyRole", inversedBy="users")
*/
private $roles;
public function __construct($email)
{
(...)
$this->roles = new ArrayCollection();
/**
*
* @return ArrayCollection list of the user's roles.
*/
public function getRoles()
{
$result = $this->roles->toArray();
return $result;
}
public function assignToRole($role)
{
$this->roles[] = $role;
}
public function setRole($myrole)
{
$this->roles= $myrole;
}
public function hasRole($role)
{
return in_array(strtoupper($role), $this->getRoles(), true);
}
public function addRole(MyRole $role)
{
$this->roles->add($role);
//$role->users->addRole($this); // could not access roles->user->...
// because private variable in MyRole but it works
}
/**
* Remove the given role from the user.
*
* @param string $role
*/
public function removeRole($role)
{
dump($role);
$this->roles->removeElement($role);
}
(...) // other setters getters
public function serialize()
{
return serialize(array(
$this->id,
$this->username,
$this->password,
$this->salt,
));
}
/**
* @see \Serializable::unserialize()
*/
public function unserialize($serialized)
{
list (
$this->id,
$this->username,
$this->password,
$this->salt,
) = unserialize($serialized);
}
}
和MyRole.php:
// MyRole.php
/**
* MyRole
*
* @Entity
* @Table(name="myrole")
*/
class MyRole implements RoleInterface
{
(...)
/**
* @ManyToMany(targetEntity="MyUser", mappedBy="roles")
*/
private $users;
/**
* @var string
* @Column(name="role", type="string", length=20, unique=true)
*/
private $role;
/*
* methods for RoleInterface
* @return string|null A string representation of the role, or null
*/
public function getRole()
{
$result = $this->role;
return ($result);
}
public function setRole($role)
{
$this->role= $role;
return $this;
}
(...)
/**
* Constructor
*/
public function __construct()
{
$this->users = new ArrayCollection();
}
/**
* Add user
* @param \MyEntities\MyUser $user
* @return MyRole
*/
public function addUser($user)
{
$this->users[] = $user;
return $this;
}
public function setUser($user)
{
$this->users[] = $user;
return $this;
}
/**
* Remove user
*
* @param \MyEntities\MyUser $user
*/
public function removeUser($user)
{
$this->users->removeElement($user);
}
/**
* Get users
*
* @return ArrayCollection $users
*/
public function getUsers()
{
return $this->users;
}
/**
* __toString()
*
* @return string
*/
public function __toString()
{
return $this->bezeichnung;
}
}
在orm命令的帮助下
vendor/bin/doctrine orm:validate-schema
vendor/bin/doctrine orm:schema-tool:update --dump-sql
生成了正确的多人表myuser\u myrole,角色设置在用户登录时起作用
我认为,最重要的是正确地使用函数addRole()(通过这个->角色->添加($role),而不是像这样->角色->添加角色($role))让doctrine在后台完成神奇的事情
谢谢你的帮助和评论!
德克我在这件事上休息了一下,但现在它似乎起作用了。谢谢miikes的addRole()建议 最后我有:MyUser.php:
//Myuser.php
/**
* MyUser
*
* @Entity
* @Table(name="myuser")
*/
class MyUser implements UserInterface, \Serializable //, ObjectManagerAware
{
...
/**
* @ManyToMany(targetEntity="MyRole", inversedBy="users")
*/
private $roles;
public function __construct($email)
{
(...)
$this->roles = new ArrayCollection();
/**
*
* @return ArrayCollection list of the user's roles.
*/
public function getRoles()
{
$result = $this->roles->toArray();
return $result;
}
public function assignToRole($role)
{
$this->roles[] = $role;
}
public function setRole($myrole)
{
$this->roles= $myrole;
}
public function hasRole($role)
{
return in_array(strtoupper($role), $this->getRoles(), true);
}
public function addRole(MyRole $role)
{
$this->roles->add($role);
//$role->users->addRole($this); // could not access roles->user->...
// because private variable in MyRole but it works
}
/**
* Remove the given role from the user.
*
* @param string $role
*/
public function removeRole($role)
{
dump($role);
$this->roles->removeElement($role);
}
(...) // other setters getters
public function serialize()
{
return serialize(array(
$this->id,
$this->username,
$this->password,
$this->salt,
));
}
/**
* @see \Serializable::unserialize()
*/
public function unserialize($serialized)
{
list (
$this->id,
$this->username,
$this->password,
$this->salt,
) = unserialize($serialized);
}
}
和MyRole.php:
// MyRole.php
/**
* MyRole
*
* @Entity
* @Table(name="myrole")
*/
class MyRole implements RoleInterface
{
(...)
/**
* @ManyToMany(targetEntity="MyUser", mappedBy="roles")
*/
private $users;
/**
* @var string
* @Column(name="role", type="string", length=20, unique=true)
*/
private $role;
/*
* methods for RoleInterface
* @return string|null A string representation of the role, or null
*/
public function getRole()
{
$result = $this->role;
return ($result);
}
public function setRole($role)
{
$this->role= $role;
return $this;
}
(...)
/**
* Constructor
*/
public function __construct()
{
$this->users = new ArrayCollection();
}
/**
* Add user
* @param \MyEntities\MyUser $user
* @return MyRole
*/
public function addUser($user)
{
$this->users[] = $user;
return $this;
}
public function setUser($user)
{
$this->users[] = $user;
return $this;
}
/**
* Remove user
*
* @param \MyEntities\MyUser $user
*/
public function removeUser($user)
{
$this->users->removeElement($user);
}
/**
* Get users
*
* @return ArrayCollection $users
*/
public function getUsers()
{
return $this->users;
}
/**
* __toString()
*
* @return string
*/
public function __toString()
{
return $this->bezeichnung;
}
}
在orm命令的帮助下
vendor/bin/doctrine orm:validate-schema
vendor/bin/doctrine orm:schema-tool:update --dump-sql
生成了正确的多人表myuser\u myrole,角色设置在用户登录时起作用
我认为,最重要的是正确地使用函数addRole()(通过这个->角色->添加($role),而不是像这样->角色->添加角色($role))让doctrine在后台完成神奇的事情
谢谢你的帮助和评论!
德克非常感谢,我尝试了两种建议。但没有更改,从getRoles()返回的数组仍然为空。我认为这种关系是正确的,因为我可以从MyUser控制器(实体类之外)访问角色。在执行登录操作时,实体中的MyUser::getRoles()会导致问题。也许我可以在登录时从其他地方访问entitymanager?您签入数据库表了吗?一切都正确吗?您还可以尝试检查多对一关系是否有效;如果我在MyUser.php中使用:公共函数getRoles(){$result=array($this->roles->getRole());return$result;}我在登录时得到了正确的角色,但这只是一个角色。你读过我的答案,关于保存许多关系的部分了吗?非常感谢,我尝试了这两个建议。但没有更改,从getRoles()返回的数组仍然为空。我认为这种关系是正确的,因为我可以从MyUser控制器(实体类之外)访问角色。在执行登录操作时,实体中的MyUser::getRoles()会导致问题。也许我可以在登录时从其他地方访问entitymanager?您签入数据库表了吗?一切都正确吗?您还可以尝试检查多对一关系是否有效。我尝试了多对一关系/***@ManyToOne(targetEntity=“MyRole”)*/