首先我们先生成验证码,之前我们已经引用了google的验证码生成器,我们先来配置一下图片验证码的生成规则:
- com.leon.config.KaptchaConfig
@Configuration
public class KaptchaConfig {
@Bean
public DefaultKaptcha producer() {
Properties properties = new Properties();
properties.put("kaptcha.border", "no");
properties.put("kaptcha.textproducer.font.color", "black");
properties.put("kaptcha.textproducer.char.space", "4");
properties.put("kaptcha.image.height", "40");
properties.put("kaptcha.image.width", "120");
properties.put("kaptcha.textproducer.font.size", "30");
Config config = new Config(properties);
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
}
上面我定义了图片验证码的长宽字体颜色等,自己可以调整哈。
然后我们通过控制器提供生成验证码的方法:
@Slf4j
@RestController
public class AuthController extends BaseController{
@Autowired
private Producer producer;
/**
* 图片验证码
*/
@GetMapping("/captcha")
public Result captcha(HttpServletRequest request, HttpServletResponse response) throws IOException {
String code = producer.createText();
String key = UUID.randomUUID().toString();
BufferedImage image = producer.createImage(code);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", outputStream);
BASE64Encoder encoder = new BASE64Encoder();
String str = "data:image/jpeg;base64,";
String base64Img = str + encoder.encode(outputStream.toByteArray());
// 存储到redis中
redisUtil.hset(Const.captcha_KEY, key, code, 120);
log.info("验证码 -- {} - {}", key, code);
return Result.succ(
MapUtil.builder()
.put("token", key)
.put("base64Img", base64Img)
.build()
);
}
}
因为前后端分离,我们禁用了session,所以我们把验证码放在了redis中,使用一个随机字符串作为key,并传送到前端,前端再把随机字符串和用户输入的验证码提交上来,这样我们就可以通过随机字符串获取到保存的验证码和用户的验证码进行比较了是否正确了。
然后因为图片验证码的方式,所以我们进行了encode,把图片进行了base64编码,这样前端就可以显示图片了。
而前端的处理,我们之前是使用了mockjs进行随机生成数据的,现在后端有接口之后,我们只需要在main.js中去掉mockjs的引入即可,这样前端就可以访问后端的接口而不被mock拦截了。