为邮件模板功能添加冗错判断,使用模块化封装的找回密码功能

This commit is contained in:
Li Jianxuan 2013-12-26 07:12:59 +00:00
parent 920b71add7
commit e8aba81d7d
6 changed files with 187 additions and 220 deletions

View File

@ -2,6 +2,7 @@
use Mail\Mail; use Mail\Mail;
use Open\Client; use Open\Client;
use Users\Account; use Users\Account;
use Users\Member;
use Helpers\Captcha; use Helpers\Captcha;
use Helpers\View as view; use Helpers\View as view;
@ -357,211 +358,92 @@ class AccountController extends Zend_Controller_Action
$this->view->captcha = $captcha->setCaptcha(); $this->view->captcha = $captcha->setCaptcha();
} }
function loadCaptcha() public function captchaAction()
{ {
$captcha = new Zend_Captcha_Image(array( if(view::isXmlHttpRequest($this))
'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',
));
return $captcha;
}
function setCaptcha(Zend_Captcha_Image $captcha,$ajax = false){
$captcha->generate();
$_SESSION['captcha'] = $captcha->getWord();
$url = $captcha->getImgUrl()
.$captcha->getId()
.$captcha->getSuffix();
if(!$ajax)
{ {
$this->view->captcha = $url; $captcha = new Captcha();
$url = $captcha->setCaptcha();
echo $url;
return true;
}else{ }else{
return $url; echo "bad request!";
exit();
} }
} }
function captchaAction()
{
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender();
$captcha = $this->loadCaptcha();
$url = $this->setCaptcha($captcha,true);
echo $url;
return true;
}
function logoutAction() public function logoutAction()
{ {
$auth = Zend_Auth::getInstance(); $auth = Zend_Auth::getInstance();
$auth->clearIdentity(); $auth->clearIdentity();
require_once 'member.php'; Member::flushcookie();
$mb=new member();
member::flushcookie();
$this->_redirect('/'); $this->_redirect('/');
}
private function default_login($u,$p)
{
$auth = Zend_Auth::getInstance();
$db=Zend_Registry::get('db');
$authAdapter = new Zend_Auth_Adapter_DbTable($db);
$authAdapter->setTableName('users')
->setIdentityColumn('username')
->setCredentialColumn('password');
$authAdapter->setIdentity($u)->setCredential(md5($p));
$result = $auth->authenticate($authAdapter);
if ($result->isValid()) {
// success: store database row to auth's storage
$data = $authAdapter->getResultRowObject(null,'password');
//头像
include_once("Avatar.php");
$avatar = new Avatar();
$data->avatar = $avatar->Get($data->email,40);
//组ID
include_once("Users.php");
$usr = new Users($db);
$data->gid = $usr->getGroup($data->id);
$auth->getStorage()->write($data);
$db->query("update users set ts_last_login=now() where username=?",array($u));
if ($this->_request->getParam('remember')) {
$sql="select usertype from users where username='$u'";
$rs=$db->query($sql);
$row=$rs->fetch();
//if($row['usertype']!='administrator')
{
require_once 'member.php';
$mb = new member();
$mb -> putcookie($u,md5($p));
}
}
return true;
}else
{
return false;
}
return false;
}
private function aspnet_login($p,$salt,$password)
{
$p1=implode("\x00",str_split($p))."\x00";
$ball=base64_decode($salt).$p1;
return trim($password)==base64_encode(sha1($ball,true));
}
// 首先判断是否存在salt
// 若有salt则按照aspnet membership加密算法进行判断
function login($u,$p)
{
$ut= new UsersTable();
$db=$ut->getAdapter();
$sql="select password,salt from users where username=?";
$uq=$db->query($sql,array($u));
if ($urow=$uq->fetchObject())
{
if (empty($urow->salt))
return $this->default_login($u,$p);
else {
//进行判断并进行转换到默认
if ($this->aspnet_login($p,$urow->salt,$urow->password))
{
$sql="update users set password=md5(?),salt='' where username=?";
$db->query($sql,array($p,$u));
return $this->default_login($u,$p);
} else
return false;
}
} else {
//没有对应的用户,登录失败
return false;
}
} }
function fetchpwdAction()
public function fetchpwdAction()
{ {
$ut= new UsersTable(); $salt = trim($this->_getParam('salt'));
$db=$ut->getAdapter();
$form = new LostpwdForm();
$key=$this->_request->getParam('key');
$login=$this->_request->getParam('login');
if (empty($key) && empty($login)) {
$this->view->form = $form;
if ($this->_request->isPost()) {
$formData = $this->_request->getPost();
if ($form->isValid($formData)) {
$sql="select * from users where email=?";
$uq=$db->query($sql,array($formData['email']));
if ($urow=$uq->fetchObject())
{
//email the url to user
$username=$urow->username;
$sql="update users set activation=? where email=?";
$uid=uniqid();
$db->query($sql,array($uid,$formData['email']));
//发邮件
$mail_template = "users-changepassword";
$mail_data = array(
'name'=>$username,
'url' => view::getHostLink()."/account/fetchpwd/".$username."/".$uid
);
$mail = new Mail();
$mail->loadTemplate($mail_template,$mail_data);
$mail->addTo($formData['email'],$username);
$mail->send();
$this->view->messages[]='请检查您的新邮件中的确认激活链接。'; if(empty($salt))
$this->view->form=false;//do not echo form {
} else $captcha = new Captcha();
$this->messenger->addMessage('对不起,没有找到对应的电子邮件地址。'); if(!empty($this->_getParam('submit')))
}
} else
$this->view->messages[]='请输入您的电子邮件地址。您将通过电子邮件收到新密码。';
} else {
$sql="select * from users where username=? and activation=?";
$uq=$db->query($sql,array($login,$key));
$tmp_pwd=uniqid();
if ($urow=$uq->fetchObject())
{ {
$sql="update users set salt='',activation='',password=md5('".$tmp_pwd."') where username=? and activation=?"; $email = trim($this->_request->getParam('email'));
$db->query($sql,array($login,$key)); $captchaword = trim($this->_request->getParam('captcha'));
//发邮件 if(!$captcha->isValid($captchaword))
$mail_template = "users-changepassword"; {
$mail_data = array( $this->view->error = view::Error("验证码错误");
'name'=>$login, $this->view->captcha = $captcha->setCaptcha();
'tmp_pwd' => $tmp_pwd return true;
); }
$mail = new Mail(); $account = new Account();
$status = $account->getMyPassword($email);
$mail->loadTemplate($mail_template,$mail_data); if(isset($status['error']))
$mail->addTo($urow->email,$login); {
$mail->send(); $this->view->error = view::Error($status['error']);
$this->view->captcha = $captcha->setCaptcha();
return true;
}
$this->view->messages[]='请查收您新邮件中的新密码'; view::Post($this,"您的密码重置申请已提交,请在邮箱中查看");
$this->view->form=false;//do not echo form return true;
}else{
} $this->view->captcha = $captcha->setCaptcha();
}//提交密码重置申请
} }
else{
$this->_helper->viewRenderer('account-resetpassword');
$this->view->salt = $salt;
if(!empty($this->_getParam('submit')))
{
$username = trim($this->_request->getParam('username'));
$password = trim($this->_request->getParam('password'));
$confirm_password = trim($this->_request->getParam('confirm_password'));
$account = new Account();
$status = $account->resetPassword(array(
'username' => $username,
'password' => $password,
'confirm_password' => $confirm_password,
'salt' => $salt
));
if(isset($status['error']))
{
$this->view->error = view::Error($status['error']);
return true;
}
view::Post($this,"您的密码修改成功!请使用新密码登录","/account/login");
return true;
}
}//修改密码
} //找回密码 } //找回密码
//OAuth2登录跳转页面 //OAuth2登录跳转页面

View File

@ -0,0 +1,41 @@
<?php
$this->headTitle($this->config->title->site);
$this->headTitle('用户登录');
$this->headTitle()->setSeparator(' - ');
$this->breadcrumb('<a href="/">首页</a>');
$this->breadcrumb('<a href="/account/login">用户登录</a>');
$this->breadcrumb()->setSeparator(' > ');
?>
<div class="row-fluid">
<?php if(!empty($this->error)) { ?>
<?= $this->error ?>
<?php } ?>
<form method="post" class="form-horizontal">
<div class="control-group">
<label class="control-label" for="username">用户名</label>
<div class="controls">
<input id="username" type="text" value="" name="username" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="password">密码</label>
<div class="controls">
<input id="password" type="password" value="" name="password" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="confirm_password">确认密码</label>
<div class="controls">
<input id="confirm_password" type="password" value="" name="confirm_password" />
</div>
</div>
<div class="control-group">
<div class="controls">
<input type="hidden" name="submit" value="1" />
<input type="hidden" name="salt" value="<?= $this->salt ?>" />
<button type="submit" class="btn">提交</button>
<a href="/account/login">登录 </a> <a href="/account/register">注册新用户</a>
</div>
</div>
</form>
</div>

View File

@ -1,24 +1,55 @@
<?php <?php
$this->headTitle($this->config->title->site); $this->headTitle($this->config->title->site);
$this->headTitle('用户登录'); $this->headTitle('用户登录');
$this->headTitle()->setSeparator(' - '); $this->headTitle()->setSeparator(' - ');
$this->headLink()->appendStylesheet('/css/register.css'); $this->headLink()->appendStylesheet('/css/register.css');
$this->breadcrumb('<a href="/">首页</a>'); $this->breadcrumb('<a href="/">首页</a>');
$this->breadcrumb('<a href="/account/fetchpwd">找回密码</a>'); $this->breadcrumb('<a href="/account/fetchpwd">找回密码</a>');
$this->breadcrumb()->setSeparator(' > '); $this->breadcrumb()->setSeparator(' > ');
?> ?>
<?php if (!empty($this->messages)) : ?> <div class="row-fluid">
<div id="message"> <?php if(!empty($this->error)) { ?>
<?php <?= $this->error ?>
foreach ($this->messages as $info)echo $info; <?php } ?>
?> <form method="post" class="form-horizontal">
</div> <div class="control-group">
<?php endif; ?> <label class="control-label" for="email">E-mail</label>
<?php if ($this->form) : ?> <div class="controls">
<div id="info"> <input id="email" type="text" value="" name="email" />
<?php echo $this->form;?> <span class="help-block">请输入注册时填写的Email地址</span>
</div> </div>
<?php endif; ?> </div>
<div id="tool"> <div class="control-group">
<a href="/account/login">登录 </a> <a href="/account/register">注册新用户</a> <label class="control-label" for="captcha">验证码</label>
</div> <div class="controls">
<input id="captcha" type="text" value="" name="captcha" />
<img id="captcha_img" src="<?php echo $this->captcha ?>" style="cursor:pointer" />
<a href="javascript:void(0);" onclick="changecaptcha()">看不清?</a>
</div>
</div>
<div class="control-group">
<div class="controls">
<input type="hidden" name="submit" value="1" />
<?php if(!empty($this->href)){?>
<input type="hidden" name="href" value="<?= $this->href ?>" />
<?php }?>
<button type="submit" class="btn">提交</button>
<a href="/account/login">登录 </a> <a href="/account/register">注册新用户</a>
</div>
</div>
</form>
</div>
<script>
$('#captcha_img').click(function(e) {
changecaptcha();
});
function changecaptcha(){
$.ajax({
url:"/account/captcha",
data:"<?= time() ?>",
success: function(src){
document.getElementById('captcha_img').src = src;
}
});
}
</script>

View File

@ -121,7 +121,12 @@ class Mail
$this->subject = $subject; $this->subject = $subject;
$this->body = $body; $this->body = $body;
$this->type = $row['type']; if(isset($row['type']))
{
$this->type = $row['type'];
}else{
$this->type = "text";
}
}//加载模板 }//加载模板

View File

@ -22,9 +22,12 @@ class Account extends \Zend_Controller_Plugin_Abstract
public $FieldRealname = "realname"; public $FieldRealname = "realname";
public $RoleMember = "member"; public $RoleMember = "member";
public $getPwdEmailTemplate = "users-changepassword"; //找回密码的邮件模板名称
public $PwdChangedEmailTemplate = "users-password-changed"; //密码修改后的邮件模板
private $db; private $db;
protected $events = NULL; //事件 protected $events = NULL; //事件
private $config;
/* /*
需要挂载的事件分别放在不同的listener中将各种操作进行模块化细分 需要挂载的事件分别放在不同的listener中将各种操作进行模块化细分
@ -304,7 +307,7 @@ class Account extends \Zend_Controller_Plugin_Abstract
return array('error'=>"此邮箱并未注册",'place'=>'email'); return array('error'=>"此邮箱并未注册",'place'=>'email');
} }
$salt = md5($email.'---'.$row['username']); $salt = md5($email.'--'.time().'--'.$row['username']);
$sql = "UPDATE {$this->memberTable} SET salt='$salt' WHERE id={$row['id']}"; $sql = "UPDATE {$this->memberTable} SET salt='$salt' WHERE id={$row['id']}";
$state = $this->db->exec($sql); $state = $this->db->exec($sql);
@ -314,15 +317,15 @@ class Account extends \Zend_Controller_Plugin_Abstract
return array('error'=>"处理中出现错误,请重试",'place'=>'email'); return array('error'=>"处理中出现错误,请重试",'place'=>'email');
} }
$mail_template = "forgotpassword";
$mail_data = array( $mail_data = array(
'name'=>$row['realname'], 'name'=>$row['realname'],
'link'=> view::getHostLink().'/account/getpassword/salt/'.$salt 'link'=> view::getHostLink().'/account/fetchpwd/?salt='.$salt,
'site' => $this->config->title->site
); );
$mail = new Mail(); $mail = new Mail();
$mail->loadTemplate($mail_template,$mail_data); $mail->loadTemplate($this->getPwdEmailTemplate,$mail_data);
$mail->addTo($email,$row['realname']); $mail->addTo($email,$row['realname']);
$mail->send(); $mail->send();
@ -358,12 +361,12 @@ class Account extends \Zend_Controller_Plugin_Abstract
$sql = "UPDATE {$this->memberTable} SET password='".md5($data['password'])."',salt='' WHERE id={$row['id']}"; $sql = "UPDATE {$this->memberTable} SET password='".md5($data['password'])."',salt='' WHERE id={$row['id']}";
$this->db->exec($sql); $this->db->exec($sql);
$mail_template = "getpassworded";
$mail_data = array( $mail_data = array(
'name'=>$row['realname'], 'name' => $row['realname'],
'site' => $this->config->title->site
); );
$mail = new Mail(); $mail = new Mail();
$mail->loadTemplate($mail_template,$mail_data); $mail->loadTemplate($this->PwdChangedEmailTemplate,$mail_data);
$mail->addTo($row['email'],$row['realname']); $mail->addTo($row['email'],$row['realname']);
$mail->send(); $mail->send();

View File

@ -58,6 +58,11 @@ class PwdOperate implements \Users\Event\PwdEvent
{ {
$data = $e->getParam('data'); $data = $e->getParam('data');
if(empty($data['salt']))
{
return array('error'=>"密钥不正确,请重新申请","place"=>'salt');
}
if(empty($data['username'])) if(empty($data['username']))
{ {
return array('error'=>"请输入用户名",'place'=>'username'); return array('error'=>"请输入用户名",'place'=>'username');
@ -70,12 +75,12 @@ class PwdOperate implements \Users\Event\PwdEvent
if(strlen($data['password']) < 6) if(strlen($data['password']) < 6)
{ {
return array('error'=>"密码长度太短为了安全最少输入6位",'place'=>'password'); return array('error'=>"密码长度太短为了安全最少输入6位",'place'=>'password');
} }
if(strlen($data['password']) > 14) if(strlen($data['password']) > 14)
{ {
return array('error'=>"密码太长,亲您记得住吗不要超过14位哦",'place'=>'password'); return array('error'=>"密码太长,请不要超过14位",'place'=>'password');
} }
if(empty($data['confirm_password'])) if(empty($data['confirm_password']))