背景:用户密码忘了,无法登录,怎么办!急!急!急!
前置工作——Srpingboot3-maven项目,核心框架如下
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jdbc</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter-test</artifactId><version>3.0.3</version><scope>test</scope></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.32</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
与数据库连接的实体类
@Data
//user用户实体类
public class userEntity {private int id;private String username;//用户private String password;//密码private String nickname;//昵称private String email;//邮箱private String userPic;//头像private LocalDateTime createTime;//创建时间private LocalDateTime updateTime;//更新时间
}
响应内容实体类
@Data
//json格式实体类
public class Result<T> {private Integer code;//0成功,1失败private boolean success;private T message;public Result(Integer code, boolean success, T message) {this.code = code;this.success = success;this.message = message;}public static <T> Result<T> success(){return new Result<>(0,true,null);}public static <T> Result<T> success(T data){return new Result<>(0,true,data);}public static <T> Result<T> error(T message){return new Result<>(1,false,message);}
}
spring:datasource:url: jdbc:mysql://localhost:3306/表?useUnicode=true&characterEncoding=utf-8username: 数据库用户password: 密码driver-class-name: com.mysql.cj.jdbc.Driver # 邮箱 # smtp服务器主机 # 端口号 # 邮箱登录账号 # 邮箱授权码mail:host: smtp.163.comport: 25username: 自己的邮箱password: 这个密码之前的文章有 # redis # 数据库 # 主机 # 端口号data:redis:database: 0host: 127.0.0.1port: 6379server:port: 1027
http://t.csdnimg.cn/vLlKW邮箱授权码教程
第一种方法:麻烦热心的管理员手动查看用户密码
第二种方法:实行一个可重复使用的函数,用来处理用户密码忘记的情况
这两种方法,我们都去尝试一下
第一种方法:
第一步:打开咱们的数据库可视化工具!(选择自己习惯的可视化工具)
第二步:新建查询
第三步:实现查询功能的SQL语句
第四步:万能的回车键!
一图流:
总流程:
我们通过一图流,和流程图可以了解到
这是一个十分简单重复的行为,你甚至不可能找出多余的流程
其次还有局限性,那就是用户都有记密码的习惯和用户量较少
java,c++,js,go,他们都具有一个统一的特性:顾客就是上帝,钱是解决问题的副产品
不管是什么语言,想要获利的首要因素就是用户需求!
用户有找回密码的需求,那么我们想获利就要实现他的需求,一个可以,两个可以,人一多,人只有24小时,总不可能24小时全程做这个吧!当然可以,短期可以,长期呢?
不是我死,就是用户死!
这还是不考虑加密的理论情况,如果是加密,数据库存的加密密码,那只能把用户刀了!
第二种方法:实行一个可重复使用的函数,用来处理用户密码忘记的情况
将采用三层架构来完成该功能,什么是三层架构,如图
观看提示,顺序为由左到右
http://t.csdnimg.cn/ovaxn邮箱发送
有些网页会通过一个与之前密码相同的操作(目前不涉及)
从上面的流程,我们可以知道需要的参数
第一个是账号,第二个是邮箱,第三个验证码,第四个密码,第五个session(里面没有啊,其实这个是发送验证码里的)
controller类
//密码找回@PostMapping("recovery")public Result<String> updateUser(@RequestParam("username") String username,@RequestParam("email") String email,@RequestParam("code") String code,@RequestParam("password") String password,HttpSession session){return Result.success("修改成功!");}
server业务接口
public interface userService{//发送emailString sendValidateEmail(String email,String session);//注册用户String addValidateUser(String username,String password,String email,String code,String session);//密码找回String recoveryPassword(String username,String email,String code,String password,String session);
}
impl实现业务层
@Service
public class userServiceImpl implements userService {@Overridepublic String recoveryPassword(String username, String email, String code, String password, String session) {return null;}
}
mapper层
@Mapper
public interface userMapping {//获取数据@Select("select * from romachen.user where username = #{message} OR email = #{message}")userEntity userByAdmitOREmail(String message);//注册@Insert("insert into romachen.user (username, password, email, create_time, update_time) values (#{username},#{password},#{email},now(),now())")int addUser(String username,String password,String email);//更新密码@Update("update romachen.user set password = #{password} ,update_time = now() where username = #{username}")int upDatePassword(String password,String username);
}
基本内容已经完成,我们从控制类开始写
控制是不包含业务逻辑的,只需要完成简单的真假判断即可
@ResourceuserService service;//密码找回@PostMapping("recovery")public Result<String> updateUser(@RequestParam("username") String username,@RequestParam("email") String email,@RequestParam("code") String code,@RequestParam("password") String password,HttpSession session){if (service.recoveryPassword(username, email, code, password, session.getId()) != null) {return Result.success("修改成功!");}return Result.error("修改失败");}
那么开始写业务层:
@Overridepublic String recoveryPassword(String username, String email, String code, String password, String session) {//对应我们发送邮件存入redis的keyString key = "email:" + session + ":" + email;//使用映射,查看数据库中对应的usernameuserEntity userEntity = mapping.userByAdmitOREmail(username);if (userEntity == null){return "该账号不存在,请您重新输入账号";}//账号为真,那么我们把账号对应的email与用户输入的email进行一个判断if (Objects.equals(userEntity.getEmail(),email)){//判断为真,我们将判断redis是否具有key,if (Boolean.TRUE.equals(template.hasKey(key))){//获取redis中的keyString s = template.opsForValue().get(key);//将key与用户输入的code判断if (Objects.equals(s,code)){String encode = new BCryptPasswordEncoder().encode(password);if (mapping.upDatePassword(encode, username)>0)return null;}else {//验证码错误return "验证码错误,请重试";}}else {//没有keyreturn "请发送邮箱";}} else {//数据库对应的邮箱与用户输入的不同return "邮箱错误,请重新输入邮箱";}return "内部问题,请联系管理员";}
然后我们的控制为了更好的配合实现层,进行一个优化
//密码找回
@PostMapping("/recovery")
public Result<String> updateUser(@RequestParam("username") String username,@RequestParam("email") String email,@RequestParam("code") String code,@RequestParam("password") String password,HttpSession session){String s = service.recoveryPassword(username, email, code, password, session.getId());if (s == null) {return Result.success("修改成功!");}return Result.error(s);
}
接口完成了,测试一下