java后端图片验证码实现

图片验证码

引入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;
    }
}
相关推荐
leikooo2 小时前
用餐厅和盘子理解栈和堆
java·数据结构·链表·rust
Ivanqhz3 小时前
激活函数在 Transformer 中的作用及各种变体简述
java·linux·数据库·人工智能·深度学习
沙漠之主4 小时前
C++编程教学设计资料:从入门到实战的完整课程方案
java·前端·c++
FPGA小徐4 小时前
PA1 基础设施(2)深度解析:NEMU 中 ITRACE、MTRACE、FTRACE、IRINGBUF、ETRACE、DIFFTEST 全解析
java·服务器·网络
YOLO数据集集合4 小时前
EvoAgent:面向PR研发治理的自进化Multi-Agent Harness系统
java·开发语言·目标检测·agent·自进化
知行EDI4 小时前
知行之桥 MaBang 端口使用指南——Create Order 订单创建篇
java·服务器·数据库
笑鸿的学习笔记4 小时前
C++笔记之大块顺序写
java·c++·笔记
打工仔折腾 AI5 小时前
从 Demo 到生产级 Agent:8 个关键设计机制与 Python 实现拆解
java·jvm·人工智能·后端·python·langchain·ai agent 实战
殷色玫瑰6 小时前
C/C++ 内存管理详解:从内存分布到 new/delete 底层原理
java·linux·c语言·c++
青山木7 小时前
Hot 100 --- 编辑距离
java·数据结构·算法·leetcode·动态规划