需求
在手机客户端中,需要手机验证码进行验证登录,需要进行手机验证码的发送,与校验。如果手机号为新用户,那么就添加新用户到用户表。
思路
过滤器设置
在之前的过滤器中需要新增可以进入的路径,以及新增方法在session中判断是否存在user对象,存在就可以进入详情页面,不存在则不能进入。
- 代码
if(request.getSession().getAttribute("user")!=null){
Long userId = (Long) request.getSession().getAttribute("user");
BaseContext.setCurrentId(userId);
filterChain.doFilter(request,response);
return;
}
验证码的发送
此部分有点坑爹,视频里面花了大篇幅来说明阿里云的短信接口,但是实际上后面并没有使用到,所以如果不想开通就可以不开通,替代方法也是有的,腾讯云自己有公众号的话可以免费使用100条,或者使用邮箱进行登录验证,不过就需要修改一下前端代码,因为有手机号格式校验。实际只需要一个写好的随机验证码工具类,这个工具类并不复杂,就是使用random生产一个4位数,或者6位数的验证码,然后return出去。
- 代码
public class ValidateCodeUtils {
/**
* 随机生成验证码
* @param length 长度为4位或者6位
* @return
*/
public static Integer generateValidateCode(int length){
Integer code =null;
if(length == 4){
code = new Random().nextInt(9999);//生成随机数,最大为9999
if(code < 1000){
code = code + 1000;//保证随机数为4位数字
}
}else if(length == 6){
code = new Random().nextInt(999999);//生成随机数,最大为999999
if(code < 100000){
code = code + 100000;//保证随机数为6位数字
}
}else{
throw new RuntimeException("只能生成4位或6位数字验证码");
}
return code;
}
/**
* 随机生成指定长度字符串验证码
* @param length 长度
* @return
*/
public static String generateValidateCode4String(int length){
Random rdm = new Random();
String hash1 = Integer.toHexString(rdm.nextInt());
String capstr = hash1.substring(0, length);
return capstr;
}
}
验证码的登录校验
- 在userController中,新建两个方法:sendMsg、login。一个用来发送验证码,一个用来校验验证码是否正确。
- 在sendMsg中,接收一个User类数据,得到前端回传的手机号码,使用工具类得到验证码,如果有用短信接口,则发送短信加上验证码,并将验证码保存到session中,为的是后期在session中取出来校验。
@PostMapping("/sendMsg")
public R<String>sendMsg(@RequestBody User user, HttpSession session){
String phoneNum = user.getPhone();
if(!StringUtils.isEmpty(phoneNum)){
String dateCode = ValidateCodeUtils.generateValidateCode(4).toString();
session.setAttribute(phoneNum,dateCode);
log.info("短信验证码:{}",dateCode);
return R.success("短信发送成功");
}
return R.error("短信发送失败");
}
- 在login方法中,使用了一种新方法接收数据。在以前的方法中,如果不是同一个类的属性,我们需要将属性打包成一个dto,直接接收一个dto对象。但是在这里,没有数组,只有两种属性:手机号码、验证码。所以直接使用map进行接收。
在map中取出手机号码和验证码,将验证码与session中的验证码进行对比,一致则登录成功。手机号码,通过LambdaQueryWrapper查询,不存在的话使用service方法进行新增。将user对象保存进session,用于过滤器判断是否登录。
@PostMapping("login")
public R<User>Login(@RequestBody Map map,HttpSession session){
String code = map.get("code").toString();
String phone = map.get("phone").toString();
Object SessionCode = session.getAttribute(phone);
if(SessionCode!=null&&SessionCode.equals(code)){
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(User::getPhone,phone);
User user = userService.getOne(queryWrapper);
if(user==null){
user = new User();
user.setPhone(phone);
userService.save(user);
}
session.setAttribute("user",user.getId());
return R.success(user);
}
return R.error("验证码错误");
}