php 在 FOSUserBundle 中管理用户/角色/组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25857472/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Managing users/roles/groups in FOSUserBundle
提问by ReynierPM
I am developing a simple CRUD to manage users/roles/groups of the application in which I am working. To manage users I'm using FOSUserBundle
. What I want to do can be accomplished in several ways:
我正在开发一个简单的 CRUD 来管理我工作的应用程序的用户/角色/组。为了管理我使用的用户FOSUserBundle
。我想做的事情可以通过几种方式完成:
- Assigning roles to groups and then assign users to these groups
- Assigning roles to users directly
- 将角色分配给组,然后将用户分配给这些组
- 直接为用户分配角色
But I have no idea how. I knew that FOSUser BaseUser
class already has a column roles
and in the documentationof FOSUser explains how to establish a ManyToMany
relationship between users and groups but do not talk anything about roles. The only idea that comes to mind is to create an entity to manage the roles as well as a form for the same purpose, something like what you see below:
但我不知道如何。我知道 FOSUserBaseUser
类已经有一个专栏roles
,在FOSUser的文档中解释了如何ManyToMany
在用户和组之间建立关系,但不谈论角色。想到的唯一想法是创建一个实体来管理角色以及出于相同目的的表单,如下所示:
Role Entity
角色实体
use Symfony\Component\Security\Core\Role\RoleInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(name="fos_role")
* @ORM\Entity(repositoryClass="UserBundle\Entity\Repository\RoleRepository")
*
* @see User
* @see \UserBundle\Role\RoleHierarchy
*
*/
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=80, unique=true)
*/
private $name;
/**
* @ORM\ManyToOne(targetEntity="Role", inversedBy="children")
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id", nullable=true)
* @var Role[]
*/
private $parent;
/**
* @ORM\OneToMany(targetEntity="Role", mappedBy="parent")
* @var ArrayCollection|Role[]
*/
private $children;
/**
* @ORM\ManyToMany(targetEntity="User", mappedBy="roles")
*/
private $users;
public function __construct($role = "")
{
if (0 !== strlen($role)) {
$this->name = strtoupper($role);
}
$this->users = new ArrayCollection();
$this->children = new ArrayCollection();
}
/**
* @see RoleInterface
*/
public function getRole()
{
return $this->name;
}
public function getId()
{
return $this->id;
}
public function setId($id)
{
$this->id = $id;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
public function getUsers()
{
return $this->users;
}
public function addUser($user, $addRoleToUser = true)
{
$this->users->add($user);
$addRoleToUser && $user->addRole($this, false);
}
public function removeUser($user)
{
$this->users->removeElement($user);
}
public function getChildren()
{
return $this->children;
}
public function addChildren(Role $child, $setParentToChild = true)
{
$this->children->add($child);
$setParentToChild && $child->setParent($this, false);
}
public function getDescendant(& $descendants = array())
{
foreach ($this->children as $role) {
$descendants[spl_object_hash($role)] = $role;
$role->getDescendant($descendants);
}
return $descendants;
}
public function removeChildren(Role $children)
{
$this->children->removeElement($children);
}
public function getParent()
{
return $this->parent;
}
public function setParent(Role $parent, $addChildToParent = true)
{
$addChildToParent && $parent->addChildren($this, false);
$this->parent = $parent;
}
public function __toString()
{
if ($this->children->count()) {
$childNameList = array();
foreach ($this->children as $child) {
$childNameList[] = $child->getName();
}
return sprintf('%s [%s]', $this->name, implode(', ', $childNameList));
}
return sprintf('%s', $this->name);
}
}
Role Form Type
角色表单类型
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class RoleType extends AbstractType {
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('parent');
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Tanane\UserBundle\Entity\Role'
));
}
/**
* @return string
*/
public function getName()
{
return 'role';
}
}
If so what would add to my user form would look something like this
如果是这样,添加到我的用户表单中的内容将如下所示
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('username', 'text')
->add('email', 'email')
->add('enabled', null, array(
'label' => 'Habilitado',
'required' => false
))
->add('rolesCollection', 'entity', array(
'class' => 'UserBundle:Role',
'multiple' => true,
'expanded' => true,
'attr' => array('class' => 'single-line-checks')
))
->add('groups', 'entity', array(
'class' => 'UserBundle:Group',
'multiple' => true,
'expanded' => true,
));
}
But I do not know if it is the right way to handle the roles since in this case would be creating a new table in my DB called fos_roles
where were the relationships between users/roles is handled but relationships between groups/roles stay out of it, then that's where I'm a little lost and need help from the more experienced in that tell me and alert if I'm on track and that would make them to achieve what I explain in the first two points. Any advice or help? How do you deal with this?
但我不知道这是否是处理角色的正确方法,因为在这种情况下将在我的数据库中创建一个新表,称为fos_roles
处理用户/角色之间的关系,但组/角色之间的关系不在其中,那么这就是我有点迷茫的地方,需要更有经验的人的帮助,告诉我并提醒我是否在正轨上,这将使他们实现我在前两点中解释的内容。有什么建议或帮助吗?你如何处理这个问题?
回答by frumious
The way FOSUserBundle deals with Roles is to store them in the roles
column that you've seen, in a serialised format like this: a:1:{i:0;s:10:"ROLE_ADMIN";}
. So there's no need for any other tables or entities^.
FOSUserBundle 处理角色的方式是将它们存储在roles
您看到的列中,以如下序列化格式:a:1:{i:0;s:10:"ROLE_ADMIN";}
。所以不需要任何其他表或实体^。
^ This is in contrast to Groups, which need to be explicitly configured, are represented by a separate Table/Entity, and do involve relating Users to Groups in the DB. Groups let you define arbitrary collections of Roles which can then be given to each User as a discrete bundle.
^这与需要显式配置的组形成对比,由单独的表/实体表示,并且确实涉及将用户与数据库中的组相关联。组让您可以定义任意角色集合,然后可以将这些角色作为离散包提供给每个用户。
A User can be a member of any number of Roles. They're identified by strings starting with "ROLE_", you can just start using a new Role.
用户可以是任意数量角色的成员。它们由以“ROLE_”开头的字符串标识,您可以开始使用新角色。
What the Roles mean for your application is completely up to you, but they're quite a high-level tool - a User is either in a particular Role or they aren't.
角色对您的应用程序意味着什么完全取决于您,但它们是一个非常高级的工具 - 用户要么处于特定角色中,要么不处于特定角色中。
You put people in Roles either via the Symfony console:
您可以通过Symfony 控制台将人员置于角色中:
php app/console fos:user:promote testuser ROLE_ADMIN
Or in PHP:
或者在 PHP 中:
$user = $this->getUser();
$userManager = $container->get('fos_user.user_manager');
$user->addRole('ROLE_ADMIN');
$userManager->updateUser($user);
And you can test membership in PHP:
您可以在 PHP 中测试会员资格:
$user = $this->getUser();
if ($user->hasRole('ROLE_ADMIN'))
{
//do something
}
Or using Annotations:
或使用注释:
/**
* @Security("has_role('ROLE_ADMIN')")
*/
public function adminAction()
{
//...
or
或者
/**
* @Security("has_role('ROLE_ADMIN')")
*/
class AdminController
{
//...
回答by neeraj
I added the functionality to add default group to the user during registration by overriding the confirmAction in Registration Controller
我通过覆盖注册控制器中的 confirmAction 添加了在注册期间向用户添加默认组的功能
What I did is I overrided the Registration Controller in my project Bundle by defining the parent to FosUserBUndle .
我所做的是通过将父级定义为 FosUserBUndle 来覆盖我的项目 Bundle 中的 Registration Controller。
Then created a function confirmedAction and in the body of the function added this code
然后创建了一个函数 ConfirmedAction 并在函数体中添加了这段代码
$repository = $em->getRepository('AdminAdminBundle:Group');
$group = $repository->findOneByName('staff');
$em = $this->getDoctrine()->getEntityManager();
$user = $this->getUser();
$user->addGroup($group);
$userManager = $this->get('fos_user.user_manager');
$userManager->updateUser($user);
if (!is_object($user) || !$user instanceof FOS\UserBundle\Model\UserInterface) {
throw new AccessDeniedException('This user does not have access to this section.');
}
return $this->render('FOSUserBundle:Registration:confirmed.html.twig',
['user' => $user]);
And it perfectly saved in db with group assignment.
并且它通过组分配完美地保存在数据库中。
Hope this will help some one in need as there is little information about the implementation in official fosuserbundle doc.
希望这会帮助有需要的人,因为官方 fosuserbundle 文档中关于实现的信息很少。