RuoYi学习(2)-登录-生成图片验证码

1,669 阅读2分钟

生成图片验证码的流程

  • 生成uuid,作为redis存储验证码结果的key
  • 根据配置的验证码类型,生成验证码图片对象,以及验证码结果
  • 将验证码结果存入redis,并设置过期时间,过期时间可以配置
  • 将验证码图片对象进行base64编码
  • 返回,图片的base64编码字符串和uuid

源码解读

/**
 * 验证码操作处理
 * 
 * @author ruoyi
 */
@RestController
public class CaptchaController
{
    //注入字符验证码生成对象
    @Resource(name = "captchaProducer")
    private Producer captchaProducer;

    //注入数学运算验证码生成对象
    @Resource(name = "captchaProducerMath")
    private Producer captchaProducerMath;

    @Autowired
    private RedisCache redisCache;
    
    // 验证码类型,可通过application.yml配置
    @Value("${ruoyi.captchaType}")
    private String captchaType;

    /**
     * 生成验证码
     */
    @GetMapping("/captchaImage")
    public AjaxResult getCode(HttpServletResponse response) throws IOException
    {
        String uuid = IdUtils.simpleUUID();
        // 生成存储验证码结果的 redis key值
        String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
        
        // capStr:验证码文本内容 code:验证码结果
        String capStr = null, code = null;
        // 创建缓冲图片对象,存储验证码图片信息
        BufferedImage image = null;

        // 生成验证码 math:数组计算 char:字符验证
        if ("math".equals(captchaType))
        {
            //生成数组计算字符串 如:3*2=?@6
            String capText = captchaProducerMath.createText();
            //截取运算等式,作为验证码文本内容 如:3*2=?
            capStr = capText.substring(0, capText.lastIndexOf("@"));
            //截取运算等式的结果,作为存储到redis的值 如:6
            code = capText.substring(capText.lastIndexOf("@") + 1);
            //将运算等式字符串,如:3*2=? 作为图片验证码内容生成缓冲图片对象
            image = captchaProducerMath.createImage(capStr);
        }
        else if ("char".equals(captchaType))
        {
            //生成字符验证码内容
            capStr = code = captchaProducer.createText();
            //将字符验证码字符串 作为图片验证码内容生成缓冲图片对象
            image = captchaProducer.createImage(capStr);
        }
        
        //将图片验证码的结果存入redis,并设置过期时间为2分钟
        redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
        
        // 转换流信息写出
        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
        
        try
        {
            //将图片以jpg格式写出到转换流os
            ImageIO.write(image, "jpg", os);
        }
        catch (IOException e)
        {
            return AjaxResult.error(e.getMessage());
        }
        
        //返回图片的base64编码字符串,以及uuid:uuid用于登录时获取验证码结果进行登录校验
        AjaxResult ajax = AjaxResult.success();
        ajax.put("uuid", uuid);
        //将图片字节数组,进行base64编码
        ajax.put("img", Base64.encode(os.toByteArray()));
        return ajax;
    }
}