我正在使用Slim Framework with Doctrine。我有三张表
id | username | password | name
--------------------------------
1 | Lorel | ******** | Lorel
id | permission | description
-------------------------------
2 | READ_ACCESS | Lorel Ipsum
id | user_id | permission_id
-----------------------------
X | 1 | 2
假设用户"1"拥有"2"权限,那么我是否可以通过使用原则找到答案。
我假设您希望进行授权。我有一个这样的设置,在Zend框架3和条令2中。关系是一样的,只是不确定如何将其转化为Slim Framework。但什么都没有;-)
用户实体与角色有关系:
/**
* @var Collection|ArrayCollection|Role[]
* @ORMManyToMany(targetEntity="UserEntityRole", inversedBy="users", fetch="LAZY")
* @ORMJoinTable(
* name="user_user_roles",
* joinColumns={@ORMJoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORMJoinColumn(name="role_id", referencedColumnName="id")}
* )
*
*/
protected $roles;
角色实体有路线,与用户相反
/**
* @var Collection|ArrayCollection|Route[]
* @ORMManyToMany(targetEntity="UserEntityRoute", inversedBy="roles", fetch="EAGER")
* @ORMJoinTable(
* name="user_role_routes",
* joinColumns={@ORMJoinColumn(name="role_id", referencedColumnName="id")},
* inverseJoinColumns={@ORMJoinColumn(name="route_id", referencedColumnName="id")}
* )
*/
protected $routes;
/**
* @var Collection|ArrayCollection|User[]
* @ORMManyToMany(targetEntity="UserEntityUser", mappedBy="roles", fetch="LAZY")
*/
protected $users;
路线实体只是与角色相反
/**
* @var Collection|ArrayCollection|Role[]
* @ORMManyToMany(targetEntity="UserEntityRole", mappedBy="routes", fetch="LAZY")
*/
protected $roles;
请注意,它涉及2关系:
- 用户<->角色
- 角色<->路线
确保初始化__construct
中的每个Collection,如下所示:
// Initialize only those within the Entity
public function __construct()
{
$this->users = new ArrayCollection();
}
生成getter方法(不需要setter!)。创建Adder/Remover方法而不是setter,就像这样(这在Route实体内):
/**
* @param Collection|ArrayCollection|Role[] $roles
*
* @return Route
*/
public function addRoles(Collection $roles) : Route
{
foreach ($roles as $role) {
if ( ! $this->getRoles()->contains($role)) {
$this->getRoles()->add($role);
}
if ( ! $role->getRoutes()->contains($this)) {
$role->getRoutes()->add($this);
}
}
return $this;
}
/**
* @param Collection|ArrayCollection|Role[] $roles
*
* @return Route
*/
public function removeRoles(Collection $roles) : Route
{
foreach ($roles as $role) {
if ($this->getRoles()->contains($role)) {
$this->getRoles()->remove($role);
}
if ($role->getRoutes()->contains($this)) {
$role->getRoutes()->remove($this);
}
}
return $this;
}
好了,这就是设置。我建议您将Gedmo条令扩展包括在内,并将@GedmoTree(type="nested")
应用于您的角色实体。使管理(嵌套/继承)角色变得容易。请参阅MySQL(和Gedmo Tree文档)中的分层数据管理
要下一步检查用户是否有权访问某个路由,您需要某种形式的AuthenticationService。因为我不了解斯利姆,所以一定要用这个框架中的东西来填充这个。不过,逻辑是一样的。我使用路由访问中包含/使用的服务,该服务检查用户是否已知(已验证),如果未分配访客角色,然后检查要访问的路由是否为任何分配的角色所知。
/**
* @param string $route
*
* @return bool
* @throws Exception
*/
public function isGranted(string $route) : bool
{
// Get assigned Role[] array or set Guest Role
if ($this->getAuthenticationService()->hasIdentity()) {
/** @var User $user */
$user = $this->getAuthenticationService()->getIdentity();
/** @var Collection|Role[] $roles */
$roles = $user->getRoles();
} else {
$roles = new ArrayCollection(
[
$this->getObjectManager()->getRepository(Role::class)->findOneBy(['name' => Role::NO_ACCOUNT_ROLE]),
]
);
}
foreach ($roles as $role) {
if ($this->checkRoutes($role, $route)) {
return true;
}
}
return false;
}
所以,我认为以上所有内容都会让你受益匪浅。
GL&高频