Springboot+redis+⾕歌开源Kaptcha实现图片验证码功能

博客 动态
0 314
羽尘
羽尘 2022-01-29 10:54:42
悬赏:0 积分 收藏

Springboot +redis+?歌开源Kaptcha实现图片验证码功能

Springboot +redis+?歌开源Kaptcha实现图片验证码功能

  • 背景
    • 注册-登录-修改密码?般需要发送验证码,但是容易被 攻击恶意调?
    • 什么是短信-邮箱轰炸机
      • 手机短信轰炸机是批、循环给?机?限发送各种? 站的注册验 证码短信的?法。
    • 公司带来的损失
      • 短信?条5分钱,如果被?盗刷?家??计算 邮箱通知不?钱,但被?盗刷,带宽、连接等都被占?,导致?法正常使?
  • 如何避免??的?站成为”?鸡“或者被刷呢
    • 增加图形验证码(开发?员)
    • 单IP请求次数限制(开发?员)
    • 限制号码发送(?般短信提供商会做)
    • 攻防永远是有的,只过加?了攻击者的成本,ROI划不 过来?然就放弃了

Kaptcha 框架介绍

  • ?歌开源的?个可?度配置的实?验证 码?成?具

    • 验证码的字体/??/颜?

    • 验证码内容的范围(数字,字?,中?汉字!)

    • 验证码图?的??,边框,边框粗细,边框颜?

    • 验证码的?扰线 验证码的样式(?眼样式、3D、普通 模糊)

  • 添加依赖

    <!--kaptcha依赖包--><dependency> <groupId>com.baomidou</groupId> <artifactId>kaptcha-spring-bootstarter</artifactId> <version>1.0.0</version> </dependency>
  • 配置类

    /** * 图像验证码的配置文件 * @author : look-word * @date : 2022-01-28 17:10 **/@Configurationpublic class CaptchaConfig {    /**     * 验证码配置     * Kaptcha配置类名     *     * @return     */    @Bean    @Qualifier("captchaProducer")    public DefaultKaptcha kaptcha() {        DefaultKaptcha kaptcha = new DefaultKaptcha();        Properties properties = new Properties();        //验证码个数        properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");        //字体间隔        properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_SPACE,"8");        //?扰线颜?        //?扰实现类        properties.setProperty(Constants.KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise");        //图?样式        properties.setProperty(Constants.KAPTCHA_OBSCURIFICATOR_IMPL,                "com.google.code.kaptcha.impl.WaterRipple");        //?字来源        properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_STRING, "0123456789");        Config config = new Config(properties);        kaptcha.setConfig(config);        return kaptcha;    }}

实战

我的配置类

获取访问ip和生成MD5的工具类

public class CommonUtil {    /**     * 获取ip     * @param request     * @return     */    public static String    getIpAddr(HttpServletRequest request) {        String ipAddress = null;        try {            ipAddress = request.getHeader("xforwarded-for");            if (ipAddress == null ||                    ipAddress.length() == 0 ||                    "unknown".equalsIgnoreCase(ipAddress)) {                ipAddress =                        request.getHeader("Proxy-Client-IP");            }            if (ipAddress == null ||                    ipAddress.length() == 0 ||                    "unknown".equalsIgnoreCase(ipAddress)) {                ipAddress =                        request.getHeader("WL-Proxy-Client-IP");            }            if (ipAddress == null ||                    ipAddress.length() == 0 ||                    "unknown".equalsIgnoreCase(ipAddress)) {                ipAddress =                        request.getRemoteAddr();                if                (ipAddress.equals("127.0.0.1")) {                    // 根据?卡取本机配置的IP                    InetAddress inet = null;                    try {                        inet =                                InetAddress.getLocalHost();                    } catch (UnknownHostException e) {                        e.printStackTrace();                    }                    ipAddress =                            inet.getHostAddress();                }            }            // 对于通过多个代理的情况,第?个IP为客户端真实IP,多个IP按照','分割            if (ipAddress != null &&                    ipAddress.length() > 15) {                // "***.***.***.***".length()                // = 15                if (ipAddress.indexOf(",") > 0)                {                    ipAddress =                            ipAddress.substring(0, ipAddress.indexOf(","));                }            }        } catch (Exception e) {            ipAddress="";        }        return ipAddress;    }    public static String MD5(String data) {        try {            java.security.MessageDigest md =                    MessageDigest.getInstance("MD5");            byte[] array =                    md.digest(data.getBytes("UTF-8"));            StringBuilder sb = new                    StringBuilder();            for (byte item : array) {                sb.append(Integer.toHexString((item & 0xFF) |                        0x100).substring(1, 3));            }            return sb.toString().toUpperCase();        } catch (Exception exception) {        }        return null;    }}

接口开发

@RestController@RequestMapping("/api/v1/captcha")public class CaptchaController {    @Autowired    private StringRedisTemplate stringRedisTemplate;        @Autowired    private Producer producer;    @RequestMapping("get_captcha")    public void getCaptcha(HttpServletRequest request, HttpServletResponse response){        String captchaText = producer.createText();        String key = getCaptchaKey(request);        // 十分钟过期        stringRedisTemplate.opsForValue().set(key,captchaText,10, TimeUnit.MINUTES);        BufferedImage image = producer.createImage(captchaText);        ServletOutputStream outputStream=null;        try {            outputStream= response.getOutputStream();            ImageIO.write(image,"jpg",outputStream);            outputStream.flush();            outputStream.close();        } catch (IOException e) {            e.printStackTrace();        }    }    /**     * 生成redis验证码模块的key     * @param request     * @return     */    private String getCaptchaKey(HttpServletRequest request){        String ipAddr = CommonUtil.getIpAddr(request);        // 请求头        String userAgent=request.getHeader("user-Agent");        String key="user_service:captcha:"+CommonUtil.MD5(ipAddr+userAgent);        return key;    }}

配置文件

server:  port: 8080spring:  redis:    host: redis锁在的ip    password: redis的密码    port: 端口号    lettuce:      pool:        # 连接池最?连接数(使?负值表示没有限制)        max-idle: 10        # 连接池中的最?空闲连接        max-active: 10        # 连接池中的最?空闲连接        min-idle: 0        # 连接池最?阻塞等待时间(使?负值表示没有限制)        max-wait: -1ms

结果

image-20220129095351726

posted @ 2022-01-29 09:57 look-word 阅读(0) 评论(0) 编辑 收藏 举报
回帖
    羽尘

    羽尘 (王者 段位)

    2335 积分 (2)粉丝 (11)源码

     

    温馨提示

    亦奇源码

    最新会员