IT评测·应用市场-qidao123.com技术社区

标题: String数据布局之验证码实战 [打印本页]

作者: 涛声依旧在    时间: 2025-4-4 19:07
标题: String数据布局之验证码实战
验证码实现我们接纳Kaptcha 框架,它是谷歌开源的一个可高度设置的实用验证码生成工具。
我们这次实现的验证码思路是:用户访问注册页面时,我们先将图形验证码在服务端生成,并存到redis中,再将该图形验证码返回给用户界面,用户输入图形验证码的值之后,点击"发送验证码"的同时,也会将电话号码以及图形验证码也一同带到服务端,服务端把吸收到的图形验证码跟redis中图形验证码是否同等。
首先我们要添加kaptcha依靠包:
  1. <dependency>
  2.       <groupId>com.baomidou</groupId>
  3.       <artifactId>kaptcha-spring-boot-starter</artifactId>
  4.       <version>1.0.0</version>
  5.     </dependency>
复制代码
验证码的设置类:
  1. @Configuration
  2. public class CaptchaConfig {
  3.     /**
  4.      * 验证码配置
  5.      * Kaptcha配置类名
  6.      *
  7.      * @return
  8.      */
  9.     @Bean
  10.     @Qualifier("captchaProducer")
  11.     public DefaultKaptcha kaptcha() {
  12.         DefaultKaptcha kaptcha = new DefaultKaptcha();
  13.         Properties properties = new Properties();
  14.         //验证码个数
  15.         properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
  16.         //字体间隔
  17.         properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_SPACE,"8");
  18.         //干扰线颜色
  19.         //干扰实现类
  20.         properties.setProperty(Constants.KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise");
  21.         //图片样式
  22.         properties.setProperty(Constants.KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.WaterRipple");
  23.         //文字来源
  24.         properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_STRING, "0123456789");
  25.         Config config = new Config(properties);
  26.         kaptcha.setConfig(config);
  27.         return kaptcha;
  28.     }
  29. }
复制代码
设置CommonUtil工具类:
  1. public class CommonUtil {
  2.     /**
  3.      * 获取ip
  4.      * @param request
  5.      * @return
  6.      */
  7.     public static String getIpAddr(HttpServletRequest request) {
  8.         String ipAddress = null;
  9.         try {
  10.             ipAddress = request.getHeader("x-forwarded-for");
  11.             if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
  12.                 ipAddress = request.getHeader("Proxy-Client-IP");
  13.             }
  14.             if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
  15.                 ipAddress = request.getHeader("WL-Proxy-Client-IP");
  16.             }
  17.             if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
  18.                 ipAddress = request.getRemoteAddr();
  19.                 if (ipAddress.equals("127.0.0.1")) {
  20.                     // 根据网卡取本机配置的IP
  21.                     InetAddress inet = null;
  22.                     try {
  23.                         inet = InetAddress.getLocalHost();
  24.                     } catch (UnknownHostException e) {
  25.                         e.printStackTrace();
  26.                     }
  27.                     ipAddress = inet.getHostAddress();
  28.                 }
  29.             }
  30.             // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
  31.             if (ipAddress != null && ipAddress.length() > 15) {
  32.                 // "***.***.***.***".length()
  33.                 // = 15
  34.                 if (ipAddress.indexOf(",") > 0) {
  35.                     ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
  36.                 }
  37.             }
  38.         } catch (Exception e) {
  39.             ipAddress="";
  40.         }
  41.         return ipAddress;
  42.     }
  43.     public static String MD5(String data)  {
  44.         try {
  45.             java.security.MessageDigest md = MessageDigest.getInstance("MD5");
  46.             byte[] array = md.digest(data.getBytes("UTF-8"));
  47.             StringBuilder sb = new StringBuilder();
  48.             for (byte item : array) {
  49.                 sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
  50.             }
  51.             return sb.toString().toUpperCase();
  52.         } catch (Exception exception) {
  53.         }
  54.         return null;
  55.     }
  56. }
复制代码
还有设置JsonData响应工具类,方便我们检察结果:
  1. public class JsonData {
  2.     /**
  3.      * 状态码 0 表示成功
  4.      */
  5.     private Integer code;
  6.     /**
  7.      * 数据
  8.      */
  9.     private Object data;
  10.     /**
  11.      * 描述
  12.      */
  13.     private String msg;
  14.     public JsonData(int code,Object data,String msg){
  15.         this.code = code;
  16.         this.data = data;
  17.         this.msg = msg;
  18.     }
  19.     /**
  20.      * 成功,不传入数据
  21.      * @return
  22.      */
  23.     public static JsonData buildSuccess() {
  24.         return new JsonData(0, null, null);
  25.     }
  26.     /**
  27.      *  成功,传入数据
  28.      * @param data
  29.      * @return
  30.      */
  31.     public static JsonData buildSuccess(Object data) {
  32.         return new JsonData(0, data, null);
  33.     }
  34.     /**
  35.      * 失败,传入描述信息
  36.      * @param msg
  37.      * @return
  38.      */
  39.     public static JsonData buildError(String msg) {
  40.         return new JsonData(-1, null, msg);
  41.     }
  42.     public Integer getCode() {
  43.         return code;
  44.     }
  45.     public void setCode(Integer code) {
  46.         this.code = code;
  47.     }
  48.     public Object getData() {
  49.         return data;
  50.     }
  51.     public void setData(Object data) {
  52.         this.data = data;
  53.     }
  54.     public String getMsg() {
  55.         return msg;
  56.     }
  57.     public void setMsg(String msg) {
  58.         this.msg = msg;
  59.     }
  60. }
复制代码
接下来我们就可以进行接口的开发:
  1. @RestController
  2. @RequestMapping("/api/v1/captcha")
  3. public class CaptchaController {
  4.     @Autowired
  5.     private StringRedisTemplate stringRedisTemplate;
  6.     @Autowired
  7.     private Producer captchaProducer;
  8.     /**
  9.      * 获取图形验证码
  10.      * @param request
  11.      * @param response
  12.      */
  13.     @GetMapping("get_captcha")
  14.     public void getCaptcha(HttpServletRequest request, HttpServletResponse response){
  15.         String captchaText = captchaProducer.createText();
  16.         String key = getCaptchaKey(request);
  17.         stringRedisTemplate.opsForValue().set(key,captchaText,10, TimeUnit.MINUTES);
  18.         BufferedImage bufferedImage = captchaProducer.createImage(captchaText);
  19.         ServletOutputStream servletOutputStream = null;
  20.         try {
  21.             servletOutputStream = response.getOutputStream();
  22.             ImageIO.write(bufferedImage,"jpg",servletOutputStream);
  23.             servletOutputStream.flush();
  24.             servletOutputStream.close();
  25.         }catch (Exception e){
  26.             e.printStackTrace();
  27.         }
  28.     }
  29.     /**
  30.      * 发送验证码
  31.      * @param to
  32.      * @param captcha
  33.      * @param request
  34.      * @return
  35.      */
  36.     @GetMapping("send_code")
  37.     public JsonData sendCode(@RequestParam(value = "to",required = true)String to,
  38.                              @RequestParam(value = "captcha",required = true)String captcha,
  39.                              HttpServletRequest request){
  40.         String key = getCaptchaKey(request);
  41.         String cacheCaptcha  = stringRedisTemplate.opsForValue().get(key);
  42.         if(captcha!=null && cacheCaptcha!=null && cacheCaptcha.equalsIgnoreCase(captcha)){
  43.             stringRedisTemplate.delete(key);
  44.             //TODO 发送验证码
  45.             return JsonData.buildSuccess();
  46.         }else {
  47.             return JsonData.buildError("验证码错误");
  48.         }
  49.     }
  50.     /**
  51.      * 获取缓存的key
  52.      * @param request
  53.      * @return
  54.      */
  55.     private String getCaptchaKey(HttpServletRequest request){
  56.         String ip = CommonUtil.getIpAddr(request);
  57.         String userAgent = request.getHeader("User-Agent");
  58.         String key = "user-service:captcha:"+CommonUtil.MD5(ip+userAgent);
  59.         return key;
  60.     }
  61. }
复制代码

 


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/) Powered by Discuz! X3.4