1)密码加密和验证
ZF2支持bcrypt和Apache(htpasswd)两种密码,都在命名空间\Zend\Crypt\Password中, ZF2推荐使用bcrypt。
加密代码:
<span style="font-size:18px;">use Zend\Crypt\Password\Bcrypt;
$bcrypt = new Bcrypt();
$securePass = $bcrypt->create('your password');//$securePass就是加密之后的代码,可以保存到数据库</span>
密码验证:
<span style="font-size:18px;">use Zend\Crypt\Password\Bcrypt;
$bcrypt = new Bcrypt();
$securePass = GetPassFromDB();//从数据库取出用户密码
$password = GetPassFromRequest();//用户输入的密码
if ($bcrypt->verify(password, $securePass)) {
//密码正确
} else {
//密码错误
}</span>
2)用户登陆的身份鉴定
用户登陆时,首先要验证用户输入的用户名和密码。
ZF2调用Zend\Authentication\Adapter\AdapterInterface接口(该接口必须实现authenticate函数)进行验证:
<span style="font-size:18px;">use Zend\Authentication\Adapter\AdapterInterface;
use Zend\Crypt\Password\Bcrypt;
use Zend\Authentication\Result;
class MyAuthAdapter implements AdapterInterface
{
/**
* @return void
*/
public function __construct($username, $password, $dbtable)
{
$this->name = strtolower($username);
$this->pwd = $password;
$this->userTable = $dbtable;
}
/**
* @return \Zend\Authentication\Result
*/
public function authenticate()
{
$code = Result::FAILURE;
$identity = $this->name;
$user = new User();
try {
$userRow = $this->userTable->getUserByName($this->name);
$bcrypt = new Bcrypt();
if ($bcrypt->verify($this->pwd, $userRow->pwd)) {
$code = Result::SUCCESS;
}
else {
$code = Result::FAILURE;
}
}
catch (\Exception $ex) {
$code = Result::FAILURE_IDENTITY_NOT_FOUND;
}
return new Result($code, $identity, array());
}
protected $name;
protected $pwd;
protected $userTable;
}</span>
密码验证通过后,要将用户身份存储下来。
ZF2调用Zend\Authentication\Storage\StorageInterface接口来存储用户身份:
<span style="font-size:18px;">use Zend\Authentication\Storage\StorageInterface;
class My\Storage implements StorageInterface
{
/**
* Returns true if and only if storage is empty
*
* @throws \Zend\Authentication\Exception\ExceptionInterface
* If it is impossible to
* determine whether storage is empty
* @return boolean
*/
public function isEmpty()
{
/**
* @todo implementation
*/
}
/**
* Returns the contents of storage
*
* Behavior is undefined when storage is empty.
*
* @throws \Zend\Authentication\Exception\ExceptionInterface
* If reading contents from storage is impossible
* @return mixed
*/
public function read()
{
/**
* @todo implementation
*/
}
/**
* Writes $contents to storage
*
* @param mixed $contents
* @throws \Zend\Authentication\Exception\ExceptionInterface
* If writing $contents to storage is impossible
* @return void
*/
public function write($contents)
{
/**
* @todo implementation
*/
}
/**
* Clears contents from storage
*
* @throws \Zend\Authentication\Exception\ExceptionInterface
* If clearing contents from storage is impossible
* @return void
*/
public function clear()
{
/**
* @todo implementation
*/
}
}</span>
可见Zend\Authentication\Storage\StorageInterface接口必须实现isEmpty、read、write、clear四个函数。
如果只需要存储在Session中的话,可以直接使用Zend\Authentication\Storage\Session类,该类已经实现了Zend\Authentication\Storage\StorageInterface接口。
<span style="font-size:18px;">use Zend\Authentication\AuthenticationService;
use Zend\Authentication\Storage\Session as SessionStorage;
//初始化ZF2的鉴定服务对象
$auth = new AuthenticationService();
//设置Zend\Authentication\Storage\StorageInterface存储接口
$auth->setStorage(new SessionStorage('someNamespace'));//someNamespace是名称空间,可以任意命名,以后都通过这个名称名称空间获取存储的身份
//创建Zend\Authentication\Adapter\AdapterInterface接口对象
$authAdapter = new MyAuthAdapter($username, $password, $dbTable);//$dbTable可以访问用户表获取用户密码
//验证用户名和密码,以及存储验证成功的身份
$result = $auth->authenticate($authAdapter);
if (!$result->isValid()) {
//鉴定失败,打印验证结果消息
foreach ($result->getMessages() as $message) {
echo "$message\n";
}
} else {
//鉴定成功,打印身份
echo $auth->getIdentity()
</span>}
3)网站的身份鉴定
在网站的其他模块中可以使用以下的代码,获取当前的用户身份:
<span style="font-size:18px;">use Zend\Authentication\AuthenticationService;
use Zend\Authentication\Storage\Session as SessionStorage;
$auth = new AuthenticationService();
$auth->setStorage(new SessionStorage('someNamespace));//someNamespace是用户登陆鉴定身份时使用的名称空间
if ($auth->hasIdentity()) {
//用户已经登录,打印用户身份
echo $auth->getIdentity();
} else {
//用户没有登录,重定向到登录界面
return $this->redirect()->toRoute('user', array('action' => 'login'));
}</span>