从0开始啃若依(前后端分离版)

669 阅读2分钟

图片验证码

image.png

本地接口地址 http://localhost/dev-api/captchaImage

响应数据

image.png

响应数据里面包含img base64位图片,状态码以及uuid

业务流程

1 前端工程加载login页面向接口发起请求

2 后端生成uuid和验证码图片并且把验证码保存在redis之中,uuid加上业务名作为key值,验证码作为value

3 将图片写入输出流再转转为byte数组同uuid一同封装进返回结果对象内然后返回给前端

@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();
    //key
    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);
        //生成BufferedImage 对象
        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;
}

细节实现

本地接口地址看起来并不是请求8080后端服务

这是因为在前端工程内二次封装了 axios对象,设置了baseUrl,使得所有的请求都带上了/dev-api

const service = axios.create({
  // axios中请求配置有baseURL选项,表示请求URL公共部分
  baseURL: process.env.VUE_APP_BASE_API,
  // 超时
  timeout: 10000
})

开发环境配置文件 image.png

跨域问题解决

在前端工程开了代理服务器,转发了带有/dev-api的请求

proxy: {
  // detail: https://cli.vuejs.org/config/#devserver-proxy
  [process.env.VUE_APP_BASE_API]: {
    target: `http://localhost:8080`,
    changeOrigin: true,
    pathRewrite: {
      ['^' + process.env.VUE_APP_BASE_API]: ''
    }
  }
},

如何生成图片验证码

if ("math".equals(captchaType))
{
    String capText = captchaProducerMath.createText();
    capStr = capText.substring(0, capText.lastIndexOf("@"));
    code = capText.substring(capText.lastIndexOf("@") + 1);
    image = captchaProducerMath.createImage(capStr);
}

1 生成一个算数表达式 (类似3+5=@6)

2 以@符号为切割算数表达式

3 前半部分用于生成图片验证码,后半部分作为验证码保存在redis之中。