图片验证码
本地接口地址 http://localhost/dev-api/captchaImage
响应数据
响应数据里面包含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
})
开发环境配置文件
跨域问题解决
在前端工程开了代理服务器,转发了带有/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之中。