很多时候,所有的用户只能得到一个角色:ROLE_USER,这是因为我们的User entity中的getRoles()的默认返回值所导致。
所以我们要在User entity中添加一个字段roles,并且把它设置成json_array类型:
1 2 3 4 5 6 7 |
// src/Acme/UserBundle/Entity/User.php // ... /** * @ORM\Column(type="json_array") */ private $roles = array(); |
json_array()允许我们存储一个字符串数组到一个字段里。在数据库中,这些数组被存储为JSON字符串。Doctrine来负责array和JSON之间的转换工作。
现在我们要更新getRoles()方法,并添加setRoles方法:
1 2 3 4 5 6 7 8 9 10 11 12 |
public function getRoles() { return $this->roles; } public function setRoles(array $roles) { $this->roles = $roles; // allows for chaining return $this; } |
很酷,但是现在的方式,用户的用户角色很可能为空。他们变成了僵尸用户,他们能够登录,但不能访问页面,我们不能让这种事情发生。
应该在getRoles()添加一些逻辑,来保证每个用户都有ROLE_USER。
1 2 3 4 5 6 7 |
public function getRoles() { $roles = $this->roles; $roles[] = 'ROLE_USER'; return array_unique($roles); } |
更新一下数据库
1 |
php app/console doctrine:schema:update --force |
让我们添加一个ROLE_ADMIN角色的用户
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// src/Acme/UserBundle/DataFixtures/ORM/LoadUsers.php // ... public function load(ObjectManager $manager) { // ... $manager->persist($user); $admin = new User(); $admin->setUsername('wayne'); $admin->setPassword($this->encodePassword($admin, 'waynepass')); $admin->setRoles(array('ROLE_ADMIN')); $manager->persist($admin); $manager->flush(); } |
运行下面命令添加数据
1 |
php app/console doctrine:fixtures:load |
现在我们用管理员登陆,debug条会显示我们有ROLE_USER和ROLE_ADMIN角色。
使用AdvancedUserBundle禁用不活跃用户
我们可以对一些不怎么来网站的用户进行禁用操作。
添加一个isActive的boolean字段到User entity。如果这个字段为假,那么程序会阻止用户进行身份验证。不要忘了在命令行运行 doctrine:generate:entities 来生成get和set方法:
1 2 3 4 5 6 7 8 9 10 11 12 |
/ src/Acme/UserBundle/Entity/User.php // ... /** * @var bool * * @ORM\Column(type="boolean") */ private $isActive = true; // ... // write or generate your getIsActive and setIsActive methods... |
在那之后,更新我们的数据库字段
1 |
php app/console doctrine:schema:update --force |
现在isActive字段已经存在了,但是它还不能的在登陆中使用。为了使他能工作,要将User类的UserInterface替换成implements AdvancedUserInterface;
1 2 3 4 5 6 7 8 9 |
// src/Acme/UserBundle/Entity/User.php // ... use Symfony\Component\Security\Core\User\AdvancedUserInterface; class User implements AdvancedUserInterface { // ... } |
这里 AdvancedUserInterface继承UserInterface。
新的接口是一个更强大的UserInterface他需要四个额外的方法。如果这些方法返回false,Symfony将阻止用户登录。为了证明这一点,除了isAccountNonLocked都返回true:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// src/Acme/UserBundle/Entity/User.php // ... public function isAccountNonExpired() { return true; } public function isAccountNonLocked() { return false; } public function isCredentialsNonExpired() { return true; } public function isEnabled() { return true; } |
现在登录不太好玩了:我们堵住了有用的信息。
这里所有的方法都在做同样的事情:就是阻止登陆。如果你想你可以翻译每个用户带来的不同信息。设置每一个都为true,除了isEnabled。让他返回isActive属性的值:
1 2 3 4 5 6 7 8 9 10 11 12 |
/ src/Acme/UserBundle/Entity/User.php // ... public function isAccountNonLocked() { return true; } public function isEnabled() { return $this->getIsActive(); } |
如果isActive为false,这应该阻止用户登录。
我们更改不活跃的用户:
1 2 3 4 5 6 7 8 9 |
// src/Acme/UserBundle/DataFixtures/ORM/LoadUsers.php // ... public function load(ObjectManager $manager) { // ... $admin->setIsActive(false); // ... } |
运行命令:
1 |
php app/console doctrine:fixtures:load |
当我们尝试登录,程序自动阻止。爽!
哈哈,学会了吧。我们可以还原程序了,让用户能够登录进来。