图片验证码
引入hutook工具依赖
xml
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.5.2</version>
</dependency>
</dependencies>
VO实体类
java
@Data
@Schema(description = "验证码响应结果实体类")
public class ValidateCodeVo {
@Schema(description = "验证码key")
private String codeKey ; // 验证码的key
@Schema(description = "验证码value")
private String codeValue ; // 图片验证码对应的字符串数据
}
底层实现
在Service层使用hutool生成图片验证码,并在controller层调用进行了
java
@Service
public class ValidateCodeServiceImpl implements ValidateCodeService {
@Autowired
private RedisTemplate<String,String> redisTemplate;
//生成图片验证码
@Override
public ValidateCodeVo generateValidateCode() {
//1 通过工具 hutool 生成图片验证码
//150:宽度,48:高度,4:验证码值数量,2:验证码划痕数量,干扰程度
CircleCaptcha circleCaptcha = CaptchaUtil.createCircleCaptcha(150, 48, 4, 2);
String codeValue = circleCaptcha.getCode();//4位验证码值
String imageBase64 = circleCaptcha.getImageBase64();//返回图片验证码,对图片进行了base64编码
//2 把验证码存储到redis里,设置redis的key:uuid redis的value:验证码值
//设置过期时间
String key = UUID.randomUUID().toString().replaceAll("-", "");
redisTemplate.opsForValue().set("user:validate"+key,codeValue,
5, TimeUnit.MINUTES);//过期时间5,单位分钟
//返回ValidateCodeVo对象
ValidateCodeVo validateCodeVo = new ValidateCodeVo();
validateCodeVo.setCodeKey(key);//redis中存储数据的key
validateCodeVo.setCodeValue("data:image/png;base64," + imageBase64);//是要把图片设置进去,格式固定,这个数据会在页面上直接通过图片的形式显示出来
return validateCodeVo;
}
}
DTO实体类
java
@Data
@Schema(description = "用户登录请求参数")
public class LoginDto {
@Schema(description = "用户名")
private String userName ;
@Schema(description = "密码")
private String password ;
@Schema(description = "提交验证码")
private String captcha ;
@Schema(description = "验证码key")
private String codeKey ;
}
验证码校验
验证码校验应该在用户登录的接口实现,和用户名密码的代码放一块
java
@Service
public class SysUserServiceImpl implements SysUserService {
@Autowired
private SysUserMapper sysUserMapper ;
@Autowired
private RedisTemplate<String,String> redisTemplate;
@Override
public LoginVo login(LoginDto loginDto) {
//1 获取输入的验证码和存储到redis的key名称
String captcha = loginDto.getCaptcha();
String key = loginDto.getCodeKey();
//2 根据获取到的redis里面的key,查询redis里面存储的验证码
String redisCode = redisTemplate.opsForValue().get("user:validate" + key);
//3 比较输入的验证码和redis存储的验证码是否一致
if(StrUtil.isEmpty(captcha) || !StrUtil.equalsIgnoreCase(redisCode,captcha)){
//4 如果不一致,提示用户校验失败
throw new GuiguException(ResultCodeEnum.VALIDATECODE_ERROR);
}
//5 如果一致,删除redis里面的验证码
redisTemplate.delete("user:validate" + key);
QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username",loginDto.getUserName());
SysUser sysUser = sysUserMapper.selectOne(queryWrapper);
if(sysUser==null){
// throw new RuntimeException("用户名不存在!");
throw new GuiguException(ResultCodeEnum.LOGIN_ERROR);
}
String input_password = DigestUtils.md5DigestAsHex(loginDto.getPassword().getBytes());
if(!sysUser.getPassword().equals(input_password)){
// throw new RuntimeException("密码不正确!");
throw new GuiguException(ResultCodeEnum.LOGIN_ERROR);
}
String token = UUID.randomUUID().toString().replaceAll("-", "");
redisTemplate.opsForValue().set("user:login"+token, JSON.toJSONString(sysUser),7, TimeUnit.DAYS);
LoginVo loginVo = new LoginVo();
loginVo.setToken(token);
return loginVo;
}
}