若依 验证码

若依验证码

后端流程

验证码的调用接口为/captchaImage,整体的流程存放在ruoyi-admin模块下的com.ruoyi.web.controller.CaptchaController中

@RestController
public class CaptchaController
{
    @Resource(name = "captchaProducer")
    private Producer captchaProducer;

    @Resource(name = "captchaProducerMath")
    private Producer captchaProducerMath;

    @Autowired
    private RedisCache redisCache;
    
    @Autowired
    private ISysConfigService configService;
    /**
     * 生成验证码
     */
    @GetMapping("/captchaImage")
    public AjaxResult getCode(HttpServletResponse response) throws IOException
    {
        AjaxResult ajax = AjaxResult.success();
        boolean captchaEnabled = configService.selectCaptchaEnabled();
        ajax.put("captchaEnabled", captchaEnabled);
        if (!captchaEnabled)
        {
            return ajax;
        }

        // 保存验证码信息
        String uuid = IdUtils.simpleUUID();
        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;

        String capStr = null, code = null;
        BufferedImage image = null;

        // 生成验证码
        String captchaType = RuoYiConfig.getCaptchaType();
        if ("math".equals(captchaType))
        {
            String capText = captchaProducerMath.createText();
            capStr = capText.substring(0, capText.lastIndexOf("@"));
            code = capText.substring(capText.lastIndexOf("@") + 1);
            image = captchaProducerMath.createImage(capStr);
        }
        else if ("char".equals(captchaType))
        {
            capStr = code = captchaProducer.createText();
            image = captchaProducer.createImage(capStr);
        }

        redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
        // 转换流信息写出
        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
        try
        {
            ImageIO.write(image, "jpg", os);
        }
        catch (IOException e)
        {
            return AjaxResult.error(e.getMessage());
        }

        ajax.put("uuid", uuid);
        ajax.put("img", Base64.encode(os.toByteArray()));
        return ajax;
    }
}

第一步 是否开启验证码

这部分的代码逻辑存放在ruoyi-system模块中,是否开启验证码的相关配置存放在sys_config表

在这里插入图片描述

//controller  
boolean captchaEnabled = configService.selectCaptchaEnabled();
ajax.put("captchaEnabled", captchaEnabled);
if (!captchaEnabled)
{
  return ajax;
}

//SysConfigServiceImpl
public boolean selectCaptchaEnabled()
{
  String captchaEnabled = selectConfigByKey("sys.account.captchaEnabled");
  if (StringUtils.isEmpty(captchaEnabled))
  {
      return true;
  }
  return Convert.toBool(captchaEnabled);
}

通过传入config_key->sys.account.captchaEnabled得到验证码是否开启的相关配置,若是false直接返回,若是true继续下面的逻辑。

其中selectConfigByKey会先读取redis中的缓存,如果缓存中不存在数据再去读取数据库中的sys_config表

在这里插入图片描述在这里插入图片描述### 第二步 生成验证码

// 获取验证码的类型  math char
String captchaType = RuoYiConfig.getCaptchaType();

在这里插入图片描述

// 保存验证码信息
String uuid = IdUtils.simpleUUID();
//captcha_codes:uuid拼接作为redis中的key
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;

String capStr = null, code = null;
BufferedImage image = null;

// 生成验证码  math char
String captchaType = RuoYiConfig.getCaptchaType();
if ("math".equals(captchaType))
{
    // 7/1=?@7
    String capText = captchaProducerMath.createText();
    // 7/1=?
    capStr = capText.substring(0, capText.lastIndexOf("@"));
    // 7
    code = capText.substring(capText.lastIndexOf("@") + 1);
    //BufferedImage
    image = captchaProducerMath.createImage(capStr);
}
else if ("char".equals(captchaType))
{
    capStr = code = captchaProducer.createText();
    image = captchaProducer.createImage(capStr);
}
//将captcha_codes:uuid 和 验证码的值7 保存到redis中
redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);

第三步 封装返回前端数据

BufferedImage是其Image抽象类的实现类,是一个带缓冲区图像类,主要作用是将一幅图片加载到内存中

// 将图片读入内存
String imgPath = "D://demo.jpg";  
BufferedImage image = ImageIO.read( new  FileInputStream(imgPath) );

// 保存图片
File outputfile  = new File("save.png");
ImageIO.write(bufferedImage,  "png",  outputfile);

FastByteArrayOutputStream是Spring框架中的一个字节数组输出流,它是对Java标准库中ByteArrayOutputStream的一个改进,提供了更高的性能和更低的内存占用

// 转换流信息写出
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
try
{
    ImageIO.write(image, "jpg", os);
}
catch (IOException e)
{
    return AjaxResult.error(e.getMessage());
}

ajax.put("uuid", uuid);
//base64对图片进行编码  
//前端 this.imageUrl = "data:image/gif;base64," + res.img;
ajax.put("img", Base64.encode(os.toByteArray()));
return ajax;

返回给前端的数据
在这里插入图片描述

前端流程

调用接口请求存放在 @/api/login

// 获取验证码  
export function getCodeImg() {
  return request({
    url: '/captchaImage',
    headers: {
      isToken: false
    },
    method: 'get',
    timeout: 20000
  })
}

/views/login.vue

getCode() {
    getCodeImg().then(res => {
        //是否有验证码
        this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled;
        if (this.captchaEnabled) {
            this.codeUrl = "data:image/gif;base64," + res.img;
            this.loginForm.uuid = res.uuid;
    	}
	});
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值