背景:用户密码忘了,无法登录,怎么办!急!急!急!
前置工作——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-8 username: 数据库用户 password: 密码 driver-class-name: com.mysql.cj.jdbc.Driver # 邮箱 # smtp服务器主机 # 端口号 # 邮箱登录账号 # 邮箱授权码 mail: host: smtp.163.com port: 25 username: 自己的邮箱 password: 这个密码之前的文章有 # redis # 数据库 # 主机 # 端口号 data: redis: database: 0 host: 127.0.0.1 port: 6379 server: port: 1027
http://t.csdnimg.cn/vLlKW邮箱授权码教程
第一种方法:麻烦热心的管理员手动查看用户密码
第二种方法:实行一个可重复使用的函数,用来处理用户密码忘记的情况
这两种方法,我们都去尝试一下
第一种方法:
第一步:打开咱们的数据库可视化工具!(选择自己习惯的可视化工具)
第二步:新建查询
第三步:实现查询功能的SQL语句
第四步:万能的回车键!
一图流:
总流程:
我们通过一图流,和流程图可以了解到
这是一个十分简单重复的行为,你甚至不可能找出多余的流程
其次还有局限性,那就是用户都有记密码的习惯和用户量较少
java,c++,js,go,他们都具有一个统一的特性:顾客就是上帝,钱是解决问题的副产品
不管是什么语言,想要获利的首要因素就是用户需求!
用户有找回密码的需求,那么我们想获利就要实现他的需求,一个可以,两个可以,人一多,人只有24小时,总不可能24小时全程做这个吧!当然可以,短期可以,长期呢?
不是我死,就是用户死!
这还是不考虑加密的理论情况,如果是加密,数据库存的加密密码,那只能把用户刀了!
第二种方法:实行一个可重复使用的函数,用来处理用户密码忘记的情况
将采用三层架构来完成该功能,什么是三层架构,如图
观看提示,顺序为由左到右
有些网页会通过一个与之前密码相同的操作(目前不涉及)
从上面的流程,我们可以知道需要的参数
第一个是账号,第二个是邮箱,第三个验证码,第四个密码,第五个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{
//发送email
String 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 {
@Override
public 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);
}
基本内容已经完成,我们从控制类开始写
控制是不包含业务逻辑的,只需要完成简单的真假判断即可
@Resource
userService 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("修改失败");
}
那么开始写业务层:
@Override
public String recoveryPassword(String username, String email, String code, String password, String session) {
//对应我们发送邮件存入redis的key
String key = "email:" + session + ":" + email;
//使用映射,查看数据库中对应的username
userEntity 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中的key
String 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 {
//没有key
return "请发送邮箱";
}
} 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);
}
接口完成了,测试一下