一、验证码简介
使用验证码的作用:防止恶意破解密码、刷票、论坛灌水、刷页、恶意注册、登录
不使用验证码的问题通过程序随机生成由大写字母、小写字母、数字、汉字组成的字符串
- 优点:生成方便,识别难易程度可调节
- 缺点:识别度不好掌握,识别度高容易被程序识别,识别度低用户体验较差
使用Java实现随机字符串验证码步骤
- 创建画板:new BufferedImage()
- 创建画笔:画板.getGraphics()
- 随机生成内容:不同颜色的字符
- 绘制内容:画笔.drawString()
存为图片发送:ImageIO.write(画板,图片类型,输出流) ```java @Component @Slf4j public class RandomCodeUtil { private final Random random = new Random();
public String randCode(int len) { if (len < 4) {
len = 4;
} // 生成字符串 StringBuilder code = new StringBuilder(); for (int i = 0; i < len; i++) {
String str = "1234567890abcdefghijklmnopqrstuvwxyz";code.append(str.charAt(random.nextInt(str.length())));
} return code.toString(); }
public Color randColor() {int r = random.nextInt(256);int g = random.nextInt(256);int b = random.nextInt(256);return new Color(r, g, b);}public void createCode(HttpServletRequest request, HttpServletResponse response) throws IOException {// 创建画板int height = 60;int width = 140;BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);// 创建画笔Graphics2D pen = img.createGraphics();// 生成随机字符串String code = randCode(4);log.info(code);request.getSession().setAttribute("randomCode", code);pen.fillRect(0, 0, width, height);int fontSize = 14;pen.setFont(new Font("微软雅黑", Font.BOLD, fontSize + random.nextInt(5)));for (int i = 0; i < code.length(); i++) {pen.setColor(randColor());pen.drawString(code.charAt(i) + "", 20 + i * fontSize, (fontSize + height) / 2 + random.nextInt(5));}ServletOutputStream out = response.getOutputStream();ImageIO.write(img,"png", out);out.flush();out.close();}
}
- controller实现```java@GetMapping("/randomCode")private void randomCode() {try {randomCodeUtil.createCode(request, response);} catch (IOException e) {e.printStackTrace();}}@GetMapping("/checkRandomCode")private String checkRandomCode(String code) {String saveCode = (String) request.getSession().getAttribute("randomCode");log.info("randomCode");if (saveCode.equalsIgnoreCase(code)) {log.info("验证码正确");return "验证码正确";} else {log.info("验证码错误");return "验证码错误";}}
三、算数验证码
@Component@Slf4jpublic class RandomCodeUtil {private final Random random = new Random();public String randCode(int len) {if (len < 4) {len = 4;}// 生成字符串StringBuilder code = new StringBuilder();for (int i = 0; i < len; i++) {String str = "1234567890abcdefghijklmnopqrstuvwxyz";code.append(str.charAt(random.nextInt(str.length())));}return code.toString();}public Color randColor() {int r = random.nextInt(256);int g = random.nextInt(256);int b = random.nextInt(256);return new Color(r, g, b);}public void createCode(HttpServletRequest request, HttpServletResponse response) throws IOException {// 创建画板int height = 60;int width = 140;BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);// 创建画笔Graphics2D pen = img.createGraphics();// 生成随机字符串String code = randCode(4);log.info(code);request.getSession().setAttribute("randomCode", code);pen.fillRect(0, 0, width, height);int fontSize = 14;pen.setFont(new Font("微软雅黑", Font.BOLD, fontSize + random.nextInt(5)));for (int i = 0; i < code.length(); i++) {pen.setColor(randColor());pen.drawString(code.charAt(i) + "", 20 + i * fontSize, (fontSize + height) / 2 + random.nextInt(5));}ServletOutputStream out = response.getOutputStream();ImageIO.write(img,"png", out);out.flush();out.close();}}
controller实现
@GetMapping("/mathCode")private void mathCode() {try {mathCodeUtil.createCode(request, response);} catch (IOException e) {log.error("生成验证码错误");}}@GetMapping("/checkMathCode")private String checkMathCode(String code) {int saveCode = (Integer) request.getSession().getAttribute("mathCode");log.info(String.valueOf(saveCode));int sendCode = Integer.parseInt(code);if (saveCode == sendCode) {log.info("验证码正确");return "验证码正确";} else {log.info("验证码错误");return "验证码错误";}}
四、kaptcha框架验证码
优点:实用,根据帮助文档进行配置即可,不用考虑实现细节
添加pom依赖
<dependency><groupId>com.github.axet</groupId><artifactId>kaptcha</artifactId><version>0.0.9</version></dependency>
实现配置类
@Configurationpublic class KaptchaConfig {@Beanpublic DefaultKaptcha producer(){Properties properties = new Properties();properties.put("kaptcha.barber","no");properties.put("kaptcha.textproducer.font.color","black");properties.put("kaptcha.textproducer.char.space","5");Config config = new Config(properties);DefaultKaptcha defaultKaptcha = new DefaultKaptcha();defaultKaptcha.setConfig(config);return defaultKaptcha;}}
写controller接口 ```java @GetMapping(“/captchCode”) private void captchCode() { response.setHeader(“Cache-Control”, “no-store”); response.setContentType(“image/jpeg”); // 文字验证码 String text = producer.createText(); log.info(text); request.getSession().setAttribute(“captchCode”, text); // 图片验证码 BufferedImage image = producer.createImage(text); // 保存验证码到session request.getSession().setAttribute(Constants.KAPTCHA_SESSION_CONFIG_KEY, text); ServletOutputStream outputStream = null; try {
outputStream = response.getOutputStream();ImageIO.write(image, "jpg", outputStream);
} catch (IOException e) {
e.printStackTrace();
} IOUtils.closeQuietly(outputStream); }
@GetMapping("/checkCapchaCode")private String checkCapchaCode(String code) {String saveCode = (String) request.getSession().getAttribute("captchCode");log.info(saveCode);if (saveCode.equalsIgnoreCase(code)) {log.info("验证码正确");return "验证码正确";} else {log.info("验证码错误");return "验证码错误";}}
