介绍
介绍
福哥带着大家完成TFUMS的忘记密码功能的通过安全问题重置密码的后一部分功能的开发。这一部分的功能和通过绑定邮箱重置密码基本一样,福哥就不详细介绍了。
大家可以对照着看【20201224】的介绍了解设计思路,基本上都是一样的设计。通过安全问题重置密码功能开发完成之后,我们的忘记密码功能就算全部完成了。
随着忘记密码功能的竣工,我们的TFUMS系统的开发也要告一段落了。经过了37节课的学习,童鞋们了解到了一个项目从零到有的开发过程。从一个一个的功能模块的设计、开发、调试的过程中,童鞋们明白了哪些场合下应该如何设计,哪些场合下应该如何处理。从TFUMS的项目开发过程当中,我们学会了图像的处理应用(用户头像上传功能),学会了电子邮件的使用技巧(绑定邮箱功能、重置密码功能),学会了Redis的基本使用技巧(用户登录功能),还学会了AES算法的应用(忘记密码的激活码和验证码)。
经过这些之后,童鞋们应该就可以自己开发一些简单的项目了!福哥在此希望有兴趣的童鞋们可以做出一些功能强大、设计精致的作品出来!!!
模型user
resetPassBySecurityQuestions
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; }
接口控制器
user_process
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"); }
视图模板
HTML代码
<!-- 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 -->
JS代码
$('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(); } });
讲解
模型user
resetPassBySecurityQuestions
首先检验Redis里是否有包含验证码MD5哈希码的值,如果有则表示用户已经使用这个验证码重置过密码了,就要拒绝再次操作。
接着校验验证码是否有效,如果无效就要报错。
然后检验用户是否存在,不存在就报错。
再来就是修改登录密码为新密码了。
最后要将验证码的MD5哈希码的值记录到Redis里,设置有效期2个小时,因为两个小时后验证码也会过期,就不存在安全问题了。
接口控制器
user_process
这是一个标准表单的处理后台程序,使用resetPassBySecurityQuestions重置用户的密码。
视图模板
HTML代码
这是重置密码表单界面,区别于修改密码表单,不需要提供原始密码。
JS代码
这是一个标准表单的JS驱动程序。
效果
重置密码表单界面。
重置完密码界面。
因为resetPassBySecurityQuestionsOK页面就是一个静态页面,福哥不在这里提供说明了,大家可以自己建立起来。
总结
福哥今天带着童鞋们完成了TFUMS系统的通过安全问题重置密码的后一部分功能的开发,同时也为TFUMS系统的教程暂时画上一个句号。
大家可以好好的总结一下经验,这可都是实实在在地项目开发经验哦~~