跟着我,“我们真的很棒”。和我们的security系统一样的棒。让我们跟上这个速度,从数据库加载用户替代security.yml中硬编码用户。
我们要做的类似于一个开源的fosuserbundle。我们要自己打造这一切,以便我们明白他是如何工作的。
生成User Entity
1 |
php app/console doctrine:generate:entity |
这个命令行替我们完成了代码的创建,我们应该在UserBundle的Entity目录下有一个User类,让我们打开它并改写表名称为yada_user:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// src/Yoda/UserBundle/Entity/User.php namespace Yoda\UserBundle\Entity; use Doctrine\ORM\Mapping as ORM; /** * @ORM\Table(name="yoda_user") * @ORM\Entity(repositoryClass="Yoda\UserBundle\Entity\UserRepository") */ class User { // ... the generated properties and getter/setter functions } |
实现UserInterface
现在我们看到的只是一个普通的doctrine实体与security并无关系。但是,我们的目标是在登录的时候从数据表加载用户。要想实现此功能,第一步是创建你的类实现UserInterface接口:
1 2 3 4 5 6 7 8 9 |
// src/Yoda/UserBundle/Entity/User.php // ... use Symfony\Component\Security\Core\User\UserInterface; class User implements UserInterface { // ... } |
这个接口需要5个方法!我们已经有两个了:getUsername()和getPassword():
1 2 3 4 5 6 7 8 9 10 11 12 |
// src/Yoda/UserBundle/Entity/User.php // ... public function getUsername() { return $this->username; } public function getPassword() { return $this->password; } |
ok,让我们添加其他3个方法:
首先,getRoles()返回一个用户角色数组。现在我们就返回一个硬编码角色,ROLE_USER。
1 2 3 4 5 6 7 |
// src/Yoda/UserBundle/Entity/User.php // ... public function getRoles() { return array('ROLE_USER'); } |
其次,添加eraseCredentials。该方法是空的。稍后我们将添加一些逻辑:
1 2 3 4 |
public function eraseCredentials() { // blank for now } |
最后,添加getSalt(),只是让他返回空即可:
1 2 3 4 |
public function getSalt() { return null; } |
我们会谈谈第二个方法:
现在,user类已经实现了UserInterface,自然symfony2的authentication系统将能够使用它。但在此之前,让我们添加yoda_user表到数据库,运行doctrine:schema:update命令:
1 |
php app/console doctrine:schema:update --force |
在security.yml中加载doctrine用户
这个很重要。我们要告诉security系统要使用我们的entity类!
在security.yml,替换encoders为我们自己的user类,并设置他的值为bcrypt
1 2 3 4 5 |
# app/config/security.yml security: encoders: Yoda\UserBundle\Entity\User: bcrypt # ... |
这是告诉symfony我们的user类中的password字段使用bcrypt算法加密。
安装password_compat
一个美中不足的问题,php5.5之前是不支持bcrypt的。所以,如果你使用php5.4或者更低版本,则需要通过Composer安装。打开你的终端,使用composer的require命令:
1 |
php composer.phar require ircmaxell/password-compat |
如果它要求版本,请使用~1.0.3版本。顺便说一下,这个require命令只是更新我们的composer.json,在里面添加了一个快捷方式。我们还需要更新composer:
1 2 3 4 |
"require": { "...": "..." "ircmaxell/password-compat": "~1.0.3" }, |
使用entity Provider
在security.yml ,移除仅有的providers,并用一个新的来替换:
1 2 3 4 5 6 7 |
# app/config/security.yml security: # ... providers: our_database_users: entity: { class: UserBundle:User, property: username } |
现在只是发明了our_database_users,这个是随便定制的名称。但是这个entity键是一个特殊的内置provider,告诉security如何通过doctrine来加载用户。
是的,这是真的吗?让我们试试吧。
当你刷新,你发现又抱错了:
1 |
There is no user provider for user "Symfony\Component\Security\Core\User\User". |
即便我们刚从security.yml删除了他,我们还是使用登录的硬编码用户。。。不要惊慌,他只是一个一次性的错误,只要刷新他,就会消失的。
下一节,创建和保存用户