步子百科步子百科

password什么意思(找回密码功能的实现)

首先表明我这个项目是什意思找实现个小项目,不存在高并发,回密不存在微服务,码功使用人数是什意思找实现个位数的....(仅用来配合目前工作使用的(非IT行业,未入行))

技术栈:后端:springboot项目;前端:vue、回密elementUI。码功思路:

由于项目比较小,什意思找实现也就不上redis了,回密直接使用mysql数据库,码功新建一个reset表 (字段:username、什意思找实现uuid)。回密

前端流程如下:

1.在登陆页中增加“找回密码”按钮:

2.点击后弹出:

3.输入“工号”后点确认:

a.工号不存在:然后整个流程结束

b.工号存在:由服务端进行相关操作后,码功返回数据(用户邮箱且进行脱敏处理)拼接显示。什意思找实现

前端的回密js代码如下:

reset () { var _this = this // name发送到后端,正确会返回其邮箱名称(后端进行了脱敏),码功否则提示name工号不存在 this.$axios.post('reset', { 'name': this.name}) .then(function (res) { if (res.data.success) { // 已发送重置密码链接至xx邮箱,如果邮箱不能接收,请联系管理员! var msg = '重置链接已发送至' + res.data.data + '邮箱,如果邮箱不能接收,请联系管理员!' _this.$notify({ title: '密码重置', message: msg, type: 'success', duration: 2000 }) _this.dialogVisible = false } else { //工号不存在时提示 _this.$notify.error({ title: '密码重置', message: '请检查工号输入是否正确', duration: 2000 }) } }) }后端发送邮件如下:

主要是reset这个api接口

uuid生成、邮箱名脱敏使用的是hutool工具。数据库框架使用的是mybatis-plus

@ResponseBody public Result<String> reset(@RequestBody Map<String,String> map) { String username = map.get("name"); User user = userDao.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUsername,username)); if (user != null) { String email = user.getEmail(); // 模拟化处理:邮箱名称脱敏 String emailto = DesensitizedUtil.email(email); // reset表中存储当前id和uuid随机字符串值 // 先查询表中是否有当前username是否存在,如果有则直接创建邮件,无则新建记录并创建邮件; Reset reset = resetMapper.selectOne(Wrappers.<Reset>lambdaQuery().eq(Reset::getUsername, username)); if (reset == null) { resetMapper.insert(new Reset(username, IdUtil.simpleUUID())); reset = resetMapper.selectOne(Wrappers.<Reset>lambdaQuery().eq(Reset::getUsername, username)); } String uuid = reset.getUuid(); //发送邮件 MimeMessage mailMessage = null; try { mailMessage = javaMailSender.createMimeMessage(); //是否发送的邮件是富文本(附件,图片,html等) MimeMessageHelper helper = new MimeMessageHelper(mailMessage, true); //发送者和接收者 helper.setFrom(from); helper.setTo(email); //邮件标题 helper.setSubject("yderp密码重置-工号:" + username); //邮件内容拼接 helper.setText("<p>用户" + username + "你好:你正在进行密码重置,本链接仅当天一次有效,请点击以下按钮进行修改:</p>\n" + "\t\t<a href=\""+myAddress+"resetPassword?uuid="+ uuid +"\""+ ">点击修改密码</a>",true); javaMailSender.send(mailMessage); }catch (Exception e) { return Result.failure(505,e.toString()); } return Result.defaultSuccess(emailto); } else { return Result.failure(506, "当前工号不存在"); } }重置密码链接页面:

需要对uuid进行判断,否则跳转到无权限页

@GetMapping("/resetPassword") public String resetPassword(String uuid){ if (uuid == null || "".equals(uuid)) { return "403"; } // 查询uuid是否有效 Reset one = resetMapper.selectOne(Wrappers.<Reset>lambdaQuery().eq(Reset::getUuid, uuid)); if (one == null) { return "403"; } return "resetPassword"; }

重置密码使用的是后端模板页面:resetPassword.html

重点是:1.获取url中uuid参数的值、

2.对新密码进行正则校验、

3.修改密码请求需要将当前uuid值传递至后端进行校验。

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>重置密码</title> <style> table { border-collapse: collapse; } [v-cloak]{ display: none !important; } </style> <script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.9.0/moment.min.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.9/vue.min.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.20.0/axios.min.js"></script> <!-- 引入组件库 --> <script src="https://unpkg.com/element-ui/lib/index.js"></script> <!-- 引入样式 --> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"> <link rel="shortcut icon" type="image/x-icon" href="/static/favicon.ico"> <script> window.onload = function () { new Vue({ el:"#main", data: { uuid: "", password: '', }, created() { this.uuid = this.GetQueryString("uuid") }, methods:{ resetPassword() { var _this = this var match = /^[a-zA-Z]\w{ 7,11}$/ if (!match.test(this.password)) { _this.$message.error('新密码以字母开头,8-12位长度') } else { axios.post('upPassword',{ password: _this.password, uuid: _this.uuid}).then(function (res) { if(res.data.success === true) { _this.$message({ message: res.data.data, type: 'success' }) }else { _this.$message.error(res.data.message) } }) } }, // 查找url中参数的方法 GetQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); var r = window.location.search.substr(1).match(reg); if (r != null) { return unescape(r[2]); } return null; } } }) } </script></head><body> <div id="main"> <div style="width: 200px;margin-top:10%;margin-left: 40%;"> <el-input v-model="password" placeholder="请输入新密码"></el-input> <div style="margin: 20px auto"> <el-button type="primary" @click="resetPassword">修改密码</el-button> </div> </div> </div> </body></html>重置密码的后端api

1.需要对前端传过来的密码再次进行正则校验;

2.需要对uuid在reset表中进行查询,如果没有数据表明链接已失效;

3.修改密码中需要对密码进行加密存储;

4.修改成功后,删除reset表中相应的记录。

//修改密码 @PostMapping("/upPassword") @ResponseBody public Result<String> upPassword(@RequestBody Map<String,String> map) { String uuid = map.get("uuid"); String password = map.get("password"); String match = "[a-zA-Z]\\w{ 7,11}"; // 密码正则验证 if (uuid == null || password == null || !password.matches(match)) { return Result.failure(501,"参数错误或密码不匹配!"); } // 查出uuid记录 Reset reset = resetMapper.selectOne(Wrappers.<Reset>lambdaQuery().eq(Reset::getUuid, uuid)); if (reset == null) { return Result.failure(502,"当前链接已失效!"); } String username = reset.getUsername(); User user = userDao.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, username)); // 然后修改密码,并且删除Reset表中相应username记录,需要加密 user.setPassword(BCrypt.hashpw((password))); int i = userDao.updateById(user); if (i > 0) { resetMapper.delete(Wrappers.<Reset>lambdaQuery().eq(Reset::getUsername,user.getUsername())); return Result.defaultSuccess("密码修改成功!"); } return Result.failure(503,"其他错误!"); }

至此,密码找回功能已经实现。当然上面的api接口均要被权限控制框架所放行。

但是还有一个问题,我们在邮箱中设置显示的是链接当天一次有效,如果当天没有打开,或者当天没有修改,在第二天依然会有效,需要的是在凌晨0点进行清除reset表的操作,需要的是一个定时任务。新建一个定时配置类:

@Configuration //1.主标记配置类@EnableScheduling // 2.开启定时任务public class ScheduleTask { private ResetMapper resetMapper; public ScheduleTask(ResetMapper resetMapper) { this.resetMapper = resetMapper; } //3.添加定时任务 每天0点执行清空表 @Scheduled(cron = "0 0 0 * * ?") private void clearReset() { //清除reset表中数据 resetMapper.clearAll(); }}@Mapper@Componentpublic interface ResetMapper extends BaseMapper<Reset> { @Update("truncate table reset") void clearAll();}

纯自学野路子来的,不要喷我,可能逻辑上或者写的格式不好看,关键是能跑得起来。