怎么用Springboot +redis+Kaptcha实现图片验证码功能


背景

  • 注册-登录-修改密码一般需要发送验证码,但是容易被攻击恶意调⽤

  • 什么是短信-邮箱轰炸机

  • 手机短信轰炸机是批、循环给手机无限发送各种网站的注册验证码短信的方法。

  • 公司带来的损失

  • 短信1条5分钱,如果被大盗刷大家自己计算 邮箱通知不用钱,但被大盗刷,带宽、连接等都被占用,导致无法正常使用

  • 如何避免自己的网站成为”肉鸡“或者被刷呢

  • 增加图形验证码(开发人员)

  • 单IP请求次数限制(开发人员)

  • 限制号码发送(一般短信提供商会做)

  • 攻防永远是有的,只过加大了攻击者的成本,ROI划不过来⾃然就放弃了

Kaptcha 框架介绍

谷歌开源的一个可高度配置的实用验证码生成工具

  • 验证码的字体/大小/颜色

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

    AILOGO AILOGO

    LOGO123旗下的AI智能LOGO生成器,只需输入品牌名称就能免费在线生成公司logo设计及配套企业VI,轻松打造您的个性品牌!

    AILOGO 139 查看详情 AILOGO
  • 验证码图⽚的大小,边框,边框粗细,边框颜色

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

添加依赖

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

配置类

/**
 * 图像验证码的配置文件
 * @author : look-word
 * @date : 2025-01-28 17:10
 **/
@Configuration
public 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");
            }
                        request.getHeader("WL-Proxy-Client-IP");
                        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.substring(0, ipAddress.indexOf(","));
        } catch (Exception e) {
            ipAddress="";
        }
        return ipAddress;
    }
    public static String MD5(String data) {
            j*a.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;
    
    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: 8080
spring:
  redis:
    host: redis锁在的ip
    password: redis的密码
    port: 端口号
    lettuce:
      pool:
        # 连接池最⼤连接数(使⽤负值表示没有限制)
        max-idle: 10
        # 连接池中的最⼤空闲连接
        max-active: 10
        # 连接池中的最⼩空闲连接
        min-idle: 0
        # 连接池最⼤阻塞等待时间(使⽤负值表示没有限制)
        max-wait: -1ms

结果

怎么用Springboot +redis+Kaptcha实现图片验证码功能

以上就是怎么用Springboot +redis+Kaptcha实现图片验证码功能的详细内容,更多请关注其它相关文章!


# SpringBoot  # kaptcha  # 验证码  # 多个  # 开发人员  # 配置文件  # 网络带宽  # redis  # 垫江seo优化  # 营销推广宣传短篇文章  # 中国男足关键词排名最新  # 广州集团推广网站建设  # 招人网站建设素材怎么写  # 关键词排名提升只选r火15星服务  # 宁夏银川市网站优化企业  # 廊坊seo外包平台  # 网站建设价格app  # QQ音乐营销推广措施  # 您的  # 池中  # 自己的  # 如何实现  # 大盗 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894


相关推荐: 苹果手机手电筒无法开启  跨语言测试实践:使用Python Selenium测试现有J*a Web项目  php如何实现多域名共享session_php存储session到redis与跨域读取配置  睡觉时心跳快是什么原因 夜间心悸如何应对  多闪APP官方下载安装入口_多闪最新版本获取入口  我居然低估了 DeepSeek,这次更新它做到了这些!  《花瓣》创建专辑方法  小米手机屏幕失灵乱跳怎么办 屏幕触控问题自检与临时解决方法【应急】  C++ cast类型转换总结_C++ reinterpret_cast与const_cast的使用  VB表达式书写规则解析  word文档行距怎么调?word文档调行距的操作步骤  人教版电子教材在线获取指南  腾讯QQ邮箱官方入口 QQ邮箱网页版登录平台  在Flask应用中安全高效地更新SQLAlchemy用户数据  如何测试您的网站全球打开速度-网站海外测速工  ao3入口镜像地址 ao3镜像入口可靠跳转  《edge浏览器》关闭翻译功能方法  视频转蓝光m2ts格式  使用逻辑应用(Logic Apps)自动处理邮件附件中的XML到Excel  《雅迪智行》用手机开锁方法  如何在Golang中处理表单文件上传_Golang 表单文件上传示例  重返未来:1999卡戎全方位攻略  QQ邮箱官方登录页_腾讯出品安全稳定的邮箱服务  如何配置VS Code作为您Git操作的默认编辑器  京东快递物流信息不更新怎么办_物流停滞原因与处理方法  汽水音乐车机版官网5.0 汽水音乐车机版5.0版本下载入口  CSS如何在页面中引入重置样式_使用Normalize.css或Reset.css统一浏览器默认样式  小红书网页版首页入口 小红书网页版电脑端官方登录链接  无人机考证官网 中国民航无人机考证官网登录入口  如何用Golang优化微服务间请求性能_Golang 微服务请求性能优化方法  Final Cut Pro视频加EQ教程  word怎么将图片设置为页面背景并不影响打印_Word图片背景设置方法  J*a列表元素格式化输出教程  PHP魔术方法__set与__isset:设计考量、性能权衡与静态分析的视角  C#中的Record类型有什么优势?C# 9新特性Record与Class的用法区别  《偃武》甘宁技能详解  Word如何将文字快速转成表格 Word文本转换成表格功能使用技巧【效率】  之了课堂app做题入口  电子白板帮助菜单使用指南  虫虫漫画排行榜单入口_虫虫漫画编辑推荐入口  firefox火狐浏览器最新官网主页_ firefox火狐浏览器平台入口直达官方链接  《360浏览器》设置摄像头权限方法  实现可重用自定义Python Range类  美发店速赢秘籍  济南公交卡手机充值指南  yandex网页版直接登录 yandex官方入口平台访问方法  Excel如何快速找到并断开外部数据源链接_Excel外部数据源断开方法  实时数据流中高效查找最小值与最大值  《小宇宙》标记不友善评论方法  稻壳阅读器官方直达网址链接 稻壳阅读器文档阅读平台主页资源入口 

 2023-05-27

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.