java-6验证码校验
1.修改SysUserServiceImpl中的login方法
在login方法中添加校验图片验证码的流程
应该将校验验证码放在校验账号和密码之前,可以减少数据库操作,提高性能
思路:
1.获取图片验证码在redis中的key
2.通过key获取验证码的value
3.如果为空或者不一致,提示用户校验失败(不区分大小写)
这里提示通过抛出自定义错误来进行
4.如果一致删除redis中的验证码
package com.atguigu.spzx.manager.service.impl;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.fastjson.JSON;
import com.atguigu.spzx.common.exception.GuiguException;
import com.atguigu.spzx.manager.mapper.SysUserMapper;
import com.atguigu.spzx.manager.service.SysUserService;
import com.atguigu.spzx.model.dto.system.LoginDto;
import com.atguigu.spzx.model.entity.system.SysUser;
import com.atguigu.spzx.model.vo.common.Result;
import com.atguigu.spzx.model.vo.common.ResultCodeEnum;
import com.atguigu.spzx.model.vo.system.LoginVo;
import com.atguigu.spzx.model.vo.system.ValidateCodeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@Service
public class SysUserServiceImpl implements SysUserService {
@Autowired()
private SysUserMapper sysUserMapper;
@Qualifier("redisTemplate")
@Autowired
private RedisTemplate redisTemplate;//通过Autowired注解注入redis实例
//登录方法
@Override
public LoginVo login(LoginDto loginDto) {
//获取图片验证码在redis中的key
String valiDateCodeKey = loginDto.getCodeKey();
//通过key获取验证码的value
String valiDateCodeValue = loginDto.getCaptcha();
String valiDateCodeValueRedis = redisTemplate.opsForValue().get("user:validateCode"+valiDateCodeKey).toString();
//如果为空或者不一致,提示用户校验失败(不区分大小写)
if(StrUtil.isEmpty(valiDateCodeValue)|| !StrUtil.equalsIgnoreCase(valiDateCodeValue,valiDateCodeValueRedis)){
throw new GuiguException(ResultCodeEnum.VALIDATECODE_ERROR);
}
//如果一致删除redis中的验证码
redisTemplate.delete(valiDateCodeKey);
//1.获取用户名
String userName = loginDto.getAccount();
//2.从数据库查询对应用户信息
SysUser sysUser = sysUserMapper.selectUserInfoByUserName(userName);
//3.如果查询不到用户信息,返回错误信息
if (sysUser == null) {
//throw new RuntimeException("用户名不存在");
throw new GuiguException(ResultCodeEnum.LOGIN_ERROR);
}
//4.如果根据用户名查询到用户信息存在
//5.获取输入的密码,比较输入的密码与数据库的密码是否一致,如果密码一致登录成功,如果密码不一致登录失败
String input_password = loginDto.getPassword();
String password = sysUser.getPassword();
//将输入的密码加密后与数据库中的密码比较,使用DigestUtils.md5Digest工具类加密
String md5_password = DigestUtils.md5DigestAsHex(input_password.getBytes());
if (!password.equals(md5_password)) {
//throw new RuntimeException("密码错误");
throw new GuiguException(ResultCodeEnum.LOGIN_ERROR);
}
//6.登录成功生成用户唯一标识token
String token = UUID.randomUUID().toString().replaceAll("-", "");
//7.把登录成的用户信息存放到redis里面
redisTemplate.opsForValue()
.set("user:login" + token, JSON.toJSONString(sysUser), 7, TimeUnit.DAYS);
//8.返回LoginVo对象
LoginVo loginVo = new LoginVo();
loginVo.setToken(token);
return loginVo;
}
}
这里注意:
SysUserServiceImpl类中的redis实例的key和value类型必须声明的和ValidateCodeServiceImpl类中一样
否则无法通过redisTemplate.opsForValue().get获取值,值永远为null