使用事件驱动的登录模块,修复cookie无法保存的bug,添加了验证码助手Helpers\Captcha

This commit is contained in:
Li Jianxuan 2013-12-26 02:50:10 +00:00
parent c2225d4e21
commit 920b71add7
6 changed files with 1041 additions and 1010 deletions

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,7 @@
</div> </div>
<? }else{ ?> <? }else{ ?>
<div class="alert alert-error alert-login"> <div class="alert alert-error alert-login">
<?= $this->error ?> <?= $this->error['error'] ?>
</div> </div>
<?php } ?> <?php } ?>
<div class="control-group"> <div class="control-group">

View File

@ -0,0 +1,52 @@
<?php
namespace Helpers;
class Captcha extends \Zend_Controller_Plugin_Abstract
{
public $captcha;
private $sessionName = "captcha";
function __construct($db = NULL)
{
$this->loadCaptcha();
}
public function loadCaptcha()
{
$this->captcha = new \Zend_Captcha_Image(array(
'captcha' => 'Image',
'wordLen' => 4,
'fontsize'=>16,
'width' => 100,
'height' => 38,
'dotNoiseLevel'=>2,
'lineNoiseLevel'=>1,
'timeout' => 300,
'font' => '../data/fonts/ggbi.ttf',
'imgDir' => 'vdimg/',
'imgUrl' => '/vdimg',
));
}
public function setCaptcha(){
$this->captcha->generate();
$_SESSION[$this->sessionName] = $this->captcha->getWord();
$url = $this->captcha->getImgUrl()
.$this->captcha->getId()
.$this->captcha->getSuffix();
return $url;
}
public function isValid($captchaword)
{
if($captchaword == $_SESSION[$this->sessionName])
{
return true;
}else{
return false;
}
}
}

View File

@ -1,372 +1,374 @@
<?php <?php
namespace Users; namespace Users;
use \Helpers\View as view; use \Helpers\View as view;
use \Helpers\dbh as dbh; use \Helpers\dbh as dbh;
use \Users\Member; use \Users\Member;
use \Mail\Mail; use \Mail\Mail;
use \Users\Listener\AccountListener; use \Users\Listener\AccountListener;
use \Users\Listener\EditListener; use \Users\Listener\EditListener;
use \Users\Listener\PwdListener; use \Users\Listener\PwdListener;
class Account extends \Zend_Controller_Plugin_Abstract class Account extends \Zend_Controller_Plugin_Abstract
{ {
public $memberTable = "users"; public $memberTable = "users";
public $FieldIndex = "id"; public $FieldIndex = "id";
public $FieldUsername = "username"; public $FieldUsername = "username";
public $FieldPasword = "password"; public $FieldPasword = "password";
public $FieldLastlogin = "ts_last_login"; public $FieldLastlogin = "ts_last_login";
public $FieldEmail = "email"; public $FieldEmail = "email";
public $FieldLastloginIp = "last_login_ip"; public $FieldLastloginIp = "last_login_ip";
public $GravatarEmailField = "gravatar_email"; public $GravatarEmailField = "gravatar_email";
public $FieldRealname = "realname"; public $FieldRealname = "realname";
public $RoleMember = "member"; public $RoleMember = "member";
private $db; private $db;
protected $events = NULL; //事件 protected $events = NULL; //事件
/* /*
需要挂载的事件分别放在不同的listener中将各种操作进行模块化细分 需要挂载的事件分别放在不同的listener中将各种操作进行模块化细分
*/ */
function __construct($initializingListener = TRUE,$db = NULL) function __construct($initializingListener = TRUE,$db = NULL)
{ {
if(empty($db)) if(empty($db))
{ {
$this->db = \Zend_Registry::get('db'); $this->db = \Zend_Registry::get('db');
}else{ }else{
$this->db = $db; $this->db = $db;
} }
$this->config = \Zend_Registry::get('config'); $this->config = \Zend_Registry::get('config');
if($initializingListener === TRUE) if($initializingListener === TRUE)
{ {
$this->loadListener(); $this->loadListener();
} }
} }
public function loadListener() public function loadListener()
{ {
//主要操作账号注册登录设置session等 //主要操作账号注册登录设置session等
$AccountListener = new AccountListener(); $AccountListener = new AccountListener();
@$this->events()->attachAggregate($AccountListener); @$this->events()->attachAggregate($AccountListener);
//账户编辑 //账户编辑
$EditListener = new EditListener(); $EditListener = new EditListener();
@$this->events()->attachAggregate($EditListener); @$this->events()->attachAggregate($EditListener);
//账户安全性(找回密码) //账户安全性(找回密码)
$PwdListener = new PwdListener(); $PwdListener = new PwdListener();
@$this->events()->attachAggregate($PwdListener); @$this->events()->attachAggregate($PwdListener);
} }
public function events(\Zend_EventManager_EventCollection $events = NULL) public function events(\Zend_EventManager_EventCollection $events = NULL)
{ {
if ($events !== NULL) { if ($events !== NULL) {
$this->events = $events; $this->events = $events;
} elseif ($this->events === NULL) { } elseif ($this->events === NULL) {
$this->events = new \Zend_EventManager_EventManager(__CLASS__); $this->events = new \Zend_EventManager_EventManager(__CLASS__);
} }
return $this->events; return $this->events;
} }
//获取账号信息,数组 //获取账号信息,数组
public function getAccountInfo($id = 0) public function getAccountInfo($id = 0)
{ {
if($id == 0) if($id == 0)
{ {
$id = view::User('id'); $id = view::User('id');
} }
$sql = "SELECT * FROM {$this->memberTable} WHERE id=$id"; $sql = "SELECT * FROM {$this->memberTable} WHERE id=$id";
$rs = $this->db->query($sql); $rs = $this->db->query($sql);
return $rs->fetch(); return $rs->fetch();
} }
//注册 //注册
public function register($data) public function register($data)
{ {
$params = compact('data'); $params = compact('data');
$results = $this->events()->trigger('register.checkParam', $this, $params); $results = $this->events()->trigger('register.checkParam', $this, $params);
$cache_data = $results->bottom(); $cache_data = $results->bottom();
if($cache_data !== true) if($cache_data !== true)
{ {
if(!is_array($cache_data)) if(!is_array($cache_data))
{ {
return array('error'=>$cache_data); return array('error'=>$cache_data);
}else{ }else{
return $cache_data; return $cache_data;
} }
} }
$results = $this->events()->trigger('register.checkUser', $this, $params); $results = $this->events()->trigger('register.checkUser', $this, $params);
$cache_data = $results->bottom(); $cache_data = $results->bottom();
if($cache_data !== true) if($cache_data !== true)
{ {
if(!is_array($cache_data)) if(!is_array($cache_data))
{ {
return array('error'=>$cache_data); return array('error'=>$cache_data);
}else{ }else{
return $cache_data; return $cache_data;
} }
} }
$loginData = array( $loginData = array(
'username'=>$data['username'], 'username'=>$data['username'],
'password'=>$data['password'] 'password'=>$data['password']
); );
$data['password'] = md5($data['password']); $data['password'] = md5($data['password']);
$data['usertype'] = "member"; $data['usertype'] = "member";
unset($data['confirm_password']); unset($data['confirm_password']);
$dbh = new dbh(); $dbh = new dbh();
$id = $dbh->insert($this->memberTable,$data,true); $id = $dbh->insert($this->memberTable,$data,true);
if(!empty($id) && is_numeric($id)) if(!empty($id) && is_numeric($id))
{ {
$this->storeLogin($loginData); $this->storeLogin($loginData);
$mb = new Member(); $mb = new Member();
$mb->putcookie($data[$this->FieldUsername],$data[$this->FieldPasword]); //username, md5(password) $mb->putcookie($data[$this->FieldUsername],$data[$this->FieldPasword]); //username, md5(password)
$params = compact('data','id'); $params = compact('data','id');
$results = $this->events()->trigger('register.success', $this, $params); $results = $this->events()->trigger('register.success', $this, $params);
return array("success" => 1); return array("success" => 1);
}else{ }else{
if($id === false) if($id === false)
{ {
return array('error'=>'服务器开小差了,请稍后再试'); return array('error'=>'服务器开小差了,请稍后再试');
}else{ }else{
return array('error'=>'服务器处理中遇到错误,请联系管理员'); return array('error'=>'服务器处理中遇到错误,请联系管理员');
} }
} }
}//register }//register
//登陆 //登陆
public function login($data) public function login($data)
{ {
$results = $this->events()->trigger('login.checkParam', $this, compact('data')); $results = $this->events()->trigger('login.checkParam', $this, compact('data'));
$cache_data = $results->bottom(); $cache_data = $results->bottom();
if($cache_data !== true) if($cache_data !== true)
{ {
if(!is_array($cache_data)) if(!is_array($cache_data))
{ {
return array('error'=>$cache_data); return array('error'=>$cache_data);
}else{ }else{
return $cache_data; return $cache_data;
} }
} }
$state = $this->storeLogin($data); $state = $this->storeLogin($data);
$mb = new Member(); $mb = new Member();
$mb->putcookie($data[$this->FieldUsername],md5($data[$this->FieldPasword])); $mb->putcookie($data[$this->FieldUsername],md5($data[$this->FieldPasword]));
return $state; return $state;
}//login }//login
//storeLogin //storeLogin
//将登录信息保存在session和cookie中 //将登录信息保存在session和cookie中
public function storeLogin($data,$md5verify = true) public function storeLogin($data,$md5verify = true)
{ {
$auth = \Zend_Auth::getInstance(); $auth = \Zend_Auth::getInstance();
$authAdapter = new \Zend_Auth_Adapter_DbTable($this->db); $authAdapter = new \Zend_Auth_Adapter_DbTable($this->db);
$authAdapter->setTableName($this->memberTable) $authAdapter->setTableName($this->memberTable)
->setIdentityColumn($this->FieldUsername) ->setIdentityColumn($this->FieldUsername)
->setCredentialColumn($this->FieldPasword); ->setCredentialColumn($this->FieldPasword);
if($data[$this->FieldPasword] == 0) if($data[$this->FieldPasword] === 0)
{ {
$password = "0"; $password = "0";
}else{ }else{
if($md5verify === false) if($md5verify == false)
{ {
$password = $data[$this->FieldPasword]; $password = $data[$this->FieldPasword];
}else{ }else{
$password = md5($data[$this->FieldPasword]); $password = md5($data[$this->FieldPasword]);
} }
} }
$authAdapter->setIdentity($data[$this->FieldUsername])->setCredential($password); $authAdapter->setIdentity($data[$this->FieldUsername])->setCredential($password);
$result = $auth->authenticate($authAdapter);
$result = $auth->authenticate($authAdapter);
if ($result->isValid()) { if ($result->isValid()) {
$user = $authAdapter->getResultRowObject(null,$this->FieldPasword); $user = $authAdapter->getResultRowObject(null,$this->FieldPasword);
$email = $user->email; $email = $user->email;
$results = $this->events()->trigger('login.success.createAvatar', $this, compact('email')); $results = $this->events()->trigger('login.success.createAvatar', $this, compact('email'));
$user->avatar = $results->bottom(); $user->avatar = $results->bottom();
$auth->getStorage()->write($user); $auth->getStorage()->write($user);
$id = $user->id; $id = $user->id;
@$results = $this->events()->trigger('login.success.updateStatus', $this, compact('id')); @$results = $this->events()->trigger('login.success.updateStatus', $this, compact('id'));
return array('success'=>1); return array('success'=>1);
} }else{
return array('error'=>'处理中发现错误,请重试'); return array("error"=>"用户信息验证失败,请重新登录");
} }
return array('error'=>'处理中发现错误,请重试');
//注册信息参数 }
public function getParam(\Zend_Controller_Request_Abstract $request)
{ //注册信息参数
$data = array( public function getParam(\Zend_Controller_Request_Abstract $request)
'username'=>$request->getParam('username'), {
'password'=>$request->getParam('password'), $data = array(
'confirm_password'=>$request->getParam('confirm_password'), 'username'=>$request->getParam('username'),
'email'=>$request->getParam('email'), 'password'=>$request->getParam('password'),
'realname'=>$request->getParam('realname') 'confirm_password'=>$request->getParam('confirm_password'),
); 'email'=>$request->getParam('email'),
return $data; 'realname'=>$request->getParam('realname')
} );
return $data;
//获取用户账户修改参数 }
public function getEditParam(\Zend_Controller_Request_Abstract $request)
{ //获取用户账户修改参数
$type = $request->getParam('type'); public function getEditParam(\Zend_Controller_Request_Abstract $request)
{
if($type == "general") $type = $request->getParam('type');
{
$data = array( if($type == "general")
'realname'=>$request->getParam('realname'), {
'signature'=>$request->getParam('signature'), $data = array(
'description'=>$request->getParam('description') 'realname'=>$request->getParam('realname'),
); 'signature'=>$request->getParam('signature'),
} 'description'=>$request->getParam('description')
);
if($type == "password") }
{
$data = array( if($type == "password")
'password' => $request->getParam('password'), {
'password_new'=>$request->getParam('password_new'), $data = array(
'password_confirm'=>$request->getParam('password_confirm') 'password' => $request->getParam('password'),
); 'password_new'=>$request->getParam('password_new'),
} 'password_confirm'=>$request->getParam('password_confirm')
return $data; );
} }
return $data;
//编辑 }
public function edit($data,$type)
{ //编辑
$results = $this->events()->trigger('edit.checkParam', $this, compact('data','type')); public function edit($data,$type)
$cache_data = $results->bottom(); {
$results = $this->events()->trigger('edit.checkParam', $this, compact('data','type'));
if($cache_data !== true) $cache_data = $results->bottom();
{
return $cache_data; if($cache_data !== true)
} {
return $cache_data;
if($type == "general") }
{
$data['signature'] = htmlspecialchars($data['signature']); if($type == "general")
$data['description'] = htmlspecialchars($data['description']); {
}else if($type == "password") $data['signature'] = htmlspecialchars($data['signature']);
{ $data['description'] = htmlspecialchars($data['description']);
$data['password'] = md5($data['password_new']); }else if($type == "password")
unset($data['password_new']); {
unset($data['password_confirm']); $data['password'] = md5($data['password_new']);
}else{ unset($data['password_new']);
return "参数错误"; unset($data['password_confirm']);
} }else{
return "参数错误";
$dbh = new dbh(); }
$uid = view::User('id');
if($dbh->update($this->memberTable,$data," id=$uid") === true) $dbh = new dbh();
{ $uid = view::User('id');
return true; if($dbh->update($this->memberTable,$data," id=$uid") === true)
}else{ {
return false; return true;
} }else{
} return false;
}
//找回密码 }
public function getMyPassword($email)
{ //找回密码
$results = $this->events()->trigger('pwd.forgot.checkParam', $this, compact('email')); public function getMyPassword($email)
$cache_data = $results->bottom(); {
$results = $this->events()->trigger('pwd.forgot.checkParam', $this, compact('email'));
if($cache_data !== true) $cache_data = $results->bottom();
{
return $cache_data; if($cache_data !== true)
} {
return $cache_data;
$sql = "SELECT * FROM {$this->memberTable} WHERE email='$email'"; }
$rs = $this->db->query($sql);
$row = $rs->fetch(); $sql = "SELECT * FROM {$this->memberTable} WHERE email='$email'";
$rs = $this->db->query($sql);
if(!isset($row['username']) || empty($row['username'])) $row = $rs->fetch();
{
return array('error'=>"此邮箱并未注册",'place'=>'email'); if(!isset($row['username']) || empty($row['username']))
} {
return array('error'=>"此邮箱并未注册",'place'=>'email');
$salt = md5($email.'---'.$row['username']); }
$sql = "UPDATE {$this->memberTable} SET salt='$salt' WHERE id={$row['id']}"; $salt = md5($email.'---'.$row['username']);
$state = $this->db->exec($sql);
$sql = "UPDATE {$this->memberTable} SET salt='$salt' WHERE id={$row['id']}";
if($state<1) $state = $this->db->exec($sql);
{
return array('error'=>"处理中出现错误,请重试",'place'=>'email'); if($state<1)
} {
return array('error'=>"处理中出现错误,请重试",'place'=>'email');
$mail_template = "forgotpassword"; }
$mail_data = array(
'name'=>$row['realname'], $mail_template = "forgotpassword";
'link'=> view::getHostLink().'/account/getpassword/salt/'.$salt $mail_data = array(
); 'name'=>$row['realname'],
'link'=> view::getHostLink().'/account/getpassword/salt/'.$salt
$mail = new Mail(); );
$mail->loadTemplate($mail_template,$mail_data); $mail = new Mail();
$mail->addTo($email,$row['realname']);
$mail->send(); $mail->loadTemplate($mail_template,$mail_data);
$mail->addTo($email,$row['realname']);
return array("success"=>1); $mail->send();
}
return array("success"=>1);
//重置密码 }
public function resetPassword($data)
{ //重置密码
$results = $this->events()->trigger('pwd.reset.checkParam', $this, compact('data')); public function resetPassword($data)
$cache_data = $results->bottom(); {
$results = $this->events()->trigger('pwd.reset.checkParam', $this, compact('data'));
if($cache_data !== true) $cache_data = $results->bottom();
{
return $cache_data; if($cache_data !== true)
} {
return $cache_data;
$sql = "SELECT * FROM {$this->memberTable} WHERE salt=?"; }
$sth = $this->db->prepare($sql);
$sth->execute(array($data['salt'])); $sql = "SELECT * FROM {$this->memberTable} WHERE salt=?";
$row = $sth->fetch(); $sth = $this->db->prepare($sql);
$sth->execute(array($data['salt']));
if(!isset($row['username']) || empty($row['username'])) $row = $sth->fetch();
{
return array('error'=>"您提供的校验码不正确,请重新申请重置密码",'place'=>'confirm_password'); if(!isset($row['username']) || empty($row['username']))
} {
return array('error'=>"您提供的校验码不正确,请重新申请重置密码",'place'=>'confirm_password');
if($row['username'] !== $data['username']) }
{
return array('error'=>"您提供的校验码不正确,请重新申请重置密码",'place'=>'confirm_password'); if($row['username'] !== $data['username'])
} {
return array('error'=>"您提供的校验码不正确,请重新申请重置密码",'place'=>'confirm_password');
$sql = "UPDATE {$this->memberTable} SET password='".md5($data['password'])."',salt='' WHERE id={$row['id']}"; }
$this->db->exec($sql);
$sql = "UPDATE {$this->memberTable} SET password='".md5($data['password'])."',salt='' WHERE id={$row['id']}";
$mail_template = "getpassworded"; $this->db->exec($sql);
$mail_data = array(
'name'=>$row['realname'], $mail_template = "getpassworded";
); $mail_data = array(
$mail = new Mail(); 'name'=>$row['realname'],
$mail->loadTemplate($mail_template,$mail_data); );
$mail->addTo($row['email'],$row['realname']); $mail = new Mail();
$mail->send(); $mail->loadTemplate($mail_template,$mail_data);
$mail->addTo($row['email'],$row['realname']);
return true; $mail->send();
} return true;
}
} }

View File

@ -1,5 +1,5 @@
<?php <?php
namespace \Users; namespace Users;
class Member class Member
{ {

View File

@ -45,9 +45,9 @@ class LoginOperate implements \Users\Event\LoginEvent
if(!empty($data['username'])) if(!empty($data['username']))
{ {
if(!preg_match("/^[a-zA-Z][a-zA-Z0-9_]{4,15}$/",$data['username'])) if(!preg_match("/^[a-zA-Z][a-zA-Z0-9_]{2,15}$/",$data['username']))
{ {
return array('error'=>"用户名应当以字母开头,由字母数字和下划线组成,并且长度在5到25个字符之间",'place'=>'username'); return array('error'=>"用户名应当以字母开头,由字母数字和下划线组成,并且长度在3到25个字符之间",'place'=>'username');
} }
} }
@ -106,6 +106,10 @@ class LoginOperate implements \Users\Event\LoginEvent
}//loginSuccess }//loginSuccess
//检查token表记录
public function checkOAuthToken()
{
}
} }