福哥带着大家完成TFUMS的忘记密码功能的通过安全问题重置密码的后一部分功能的开发。这一部分的功能和通过绑定邮箱重置密码基本一样,福哥就不详细介绍了。
大家可以对照着看【20201224】的介绍了解设计思路,基本上都是一样的设计。通过安全问题重置密码功能开发完成之后,我们的忘记密码功能就算全部完成了。
随着忘记密码功能的竣工,我们的TFUMS系统的开发也要告一段落了。经过了37节课的学习,童鞋们了解到了一个项目从零到有的开发过程。从一个一个的功能模块的设计、开发、调试的过程中,童鞋们明白了哪些场合下应该如何设计,哪些场合下应该如何处理。从TFUMS的项目开发过程当中,我们学会了图像的处理应用(用户头像上传功能),学会了电子邮件的使用技巧(绑定邮箱功能、重置密码功能),学会了Redis的基本使用技巧(用户登录功能),还学会了AES算法的应用(忘记密码的激活码和验证码)。
经过这些之后,童鞋们应该就可以自己开发一些简单的项目了!福哥在此希望有兴趣的童鞋们可以做出一些功能强大、设计精致的作品出来!!!
public function resetPassBySecurityQuestions(string $dataEncrypted, string $newPwd):bool {
$tfdo = $this->tfphp->getDatabase()->getTFDO();
$tfredis = $this->tfphp->getDatabase()->getRedis();
$myAES = new TFAES($this->tfphp);
$dataMD5Key = md5($dataEncrypted). "resetPassBySecurityQuestions";
if($tfredis->get($dataMD5Key) == $dataEncrypted){
return 1;
}
$timestamp = date("YmdH0000");
$data = $myAES->decrypt($dataEncrypted, TFConfig::get("projectAESPK", "system"). $timestamp, "");
$arr = unserialize($data);
if(!is_array($arr)
|| $arr['action'] != "resetPassBySecurityQuestions"
|| $arr['id'] == 0){
$timestamp = date("YmdH0000", strtotime("-1 hour"));
$data = $myAES->decrypt($dataEncrypted, TFConfig::get("projectAESPK", "system"). $timestamp, "");
$arr = unserialize($data);
if(!is_array($arr)
|| $arr['action'] != "resetPassBySecurityQuestions"
|| $arr['id'] == 0){
return 1;
}
}
$userID = $arr['id'];
$userInfo = $this->getByTable("user", array($userID));
if($userInfo == null){
return 2;
}
$ret = $tfdo->update("user", array(
'passwd'=>md5($newPwd)
), null, "userID = @int", array(
$userID
));
if(!$ret){
return 3;
}
$tfredis->set($dataMD5Key, $dataEncrypted);
$tfredis->expire($dataMD5Key, 7200);
return 0;
}protected function user_process(){
$req = $this->tfphp->getRequest();
$post = $req->post;
$user = new user($this->tfphp);
$data = $req->get->sn;
$npass = $post->get("npass");
$cpass = $post->get("cpass");
try{
// request test
if($npass == "" || $cpass == ""){
return $this->tfphp->getResponse()->responseJSON_CM(200, 1001101, "错误请求");
}
if($npass != $cpass){
return $this->tfphp->getResponse()->responseJSON_CM(200, 1001101, "两次输入的新密码不一样");
}
// forgot by email
$ret = $user->resetPassBySecurityQuestions($data, $npass);
switch ($ret){
case 1:
return $this->tfphp->getResponse()->responseJSON_CM(200, 1001102, "验证码无效");
break;
case 2:
return $this->tfphp->getResponse()->responseJSON_CM(200, 1001103, "用户不存在");
break;
case 3:
return $this->tfphp->getResponse()->responseJSON_CM(200, 1001104, "重置密码失败");
break;
}
}
catch(\TypeError $e){
return $this->tfphp->getResponse()->responseJSON_CM(200, 1001101, "错误请求");
}
// output
return $this->tfphp->getResponse()->responseJSON_CM(200, 0, "OK");
}<!-- bind Email form begin --> <div class="row login-form"> <div class="col-sm-12"> <h3 class="text-center">重置密码</h3> <p>请输入您的新密码</p> <form> <div class="form-group"> <label>新密码</label> <input class="form-control" type="password" name="npass" /> </div> <div class="form-group"> <label>新确认密码</label> <input class="form-control" type="password" name="cpass" /> </div> <div class="form-group"> <button class="btn btn-primary btn-sm form-control">重置密码</button> </div> </form> </div> </div> <!-- bind Email form end -->
$('form').form({
url: "<% $TFReq->server->BASE_URI %>api/member/resetPassBySecurityQuestions?sn=<% $TFReq->get->data %>",
method: "post",
validations: [
{type:"empty", name:"npass", msg:"请填写新密码"},
{type:"min", value:6, name:"npass", msg:"新密码最少6个字"},
{type:"empty", name:"cpass", msg:"请填写新确认密码"}
],
onSuccess: function (d) {
if(d.errcode == 0){
document.location = '<% $TFReq->server->BASE_URI %>resetPassBySecurityQuestionsOK.htm?sn=<% $TFReq->get->data %>';
}
else{
$('form').tips({
text:d.errmsg
});
}
},
onError: function (d) {
$('form').tips({
text:"服务器响应错误"
});
},
onValidationError: function (form, name, msg) {
$('form').tips({
text:msg
});
$('form').find('[name="'+ name +'"]').focus();
}
});首先检验Redis里是否有包含验证码MD5哈希码的值,如果有则表示用户已经使用这个验证码重置过密码了,就要拒绝再次操作。
接着校验验证码是否有效,如果无效就要报错。
然后检验用户是否存在,不存在就报错。
再来就是修改登录密码为新密码了。
最后要将验证码的MD5哈希码的值记录到Redis里,设置有效期2个小时,因为两个小时后验证码也会过期,就不存在安全问题了。
这是一个标准表单的处理后台程序,使用resetPassBySecurityQuestions重置用户的密码。
这是重置密码表单界面,区别于修改密码表单,不需要提供原始密码。
这是一个标准表单的JS驱动程序。
重置密码表单界面。

重置完密码界面。
因为resetPassBySecurityQuestionsOK页面就是一个静态页面,福哥不在这里提供说明了,大家可以自己建立起来。

福哥今天带着童鞋们完成了TFUMS系统的通过安全问题重置密码的后一部分功能的开发,同时也为TFUMS系统的教程暂时画上一个句号。
大家可以好好的总结一下经验,这可都是实实在在地项目开发经验哦~~