0


Java实现图片验证码功能

文章目录

一、背景

在实现登录功能时,为了防止特定的程序暴力破解,一般为了安全都会在用户登录时增加otp动态验证码录。otp验证码 otp全称叫One-time Password,也称动态口令,是指计算机系统或其他数字设备上只能使用一次的密码,有效期为只有一次登录会话或很短。

常见验证码分为图片验证码和短信验证码,还有滑动窗口模块和选中指定物体验证方式。下面通过Java来实现图片验证码示例,效果如下:

在这里插入图片描述

二、实现步骤

1、maven中加入依赖

pom.xml引入依赖:

<dependency><groupId>com.github.penggle</groupId><artifactId>kaptcha</artifactId><version>2.3.2</version></dependency><dependency><groupId>com.github.whvcse</groupId><artifactId>easy-captcha</artifactId><version>1.6.2</version></dependency>

2、CaptchaController.java

/**
     * 验证码
     */@GetMapping("/captcha/digit")@ApiOperation(value ="获取数字验证码", notes ="获取数字验证码", tags ="验证码相关")@ApiImplicitParams({@ApiImplicitParam(name ="uuid", value ="uuid", required =true, paramType ="query")})@PassTokenpublicvoidcaptcha(HttpServletResponse response,String uuid)throwsIOException{
        response.setHeader("Cache-Control","no-store, no-cache");
        response.setContentType("image/jpeg");
        log.info("获取验证码,uuid:{}", uuid);//获取图片验证码BufferedImage image = captchaService.getCaptcha(uuid);
        log.info("获取验证码,uuid:{},return:{}", uuid, JSON.toJSONString(image));ServletOutputStream out = response.getOutputStream();ImageIO.write(image,"jpg", out);IOUtils.closeQuietly(out);}@GetMapping("/captcha/graphics")@ApiOperation(value ="获取图形验证码", notes ="获取图形验证码", tags ="验证码相关")@ApiImplicitParams({@ApiImplicitParam(name ="uuid", value ="uuid", required =true, paramType ="query"),@ApiImplicitParam(name ="type", value ="类型 png:png gif:gif cn:中文 cngif:中文gif arithmeti:算术", required =false, paramType ="query")})publicvoidcaptcha(HttpServletRequest request,HttpServletResponse response,@RequestParamString uuid,@RequestParam(defaultValue ="arithmeti", required =false)String type)throwsException{// 设置请求头为输出图片类型
        response.setContentType("image/gif");
        response.setHeader("Pragma","No-cache");
        response.setHeader("Cache-Control","no-cache");
        response.setDateHeader("Expires",0);Captcha captcha =null;switch(type){case"png":
                captcha =newSpecCaptcha(130,48);break;case"gif":// gif类型
                captcha =newGifCaptcha(130,48);break;case"cn":// 中文类型
                captcha =newChineseCaptcha(130,48,5,newFont("楷体",Font.PLAIN,28));break;case"cngif":// 中文gif类型
                captcha =newChineseGifCaptcha(130,48,5,newFont("楷体",Font.PLAIN,28));break;case"arithmeti":// 算术类型ArithmeticCaptcha arithmeticCaptcha =newArithmeticCaptcha(130,48);
                arithmeticCaptcha.setLen(3);// 几位数运算,默认是两位
                arithmeticCaptcha.getArithmeticString();// 获取运算的公式:3+2=?
                arithmeticCaptcha.text();// 获取运算的结果:5
                captcha = arithmeticCaptcha;break;default:newSpecCaptcha(130,48);break;}
        log.info("验证码:{}", captcha.text());// 设置字体//        captcha.setFont(new Font("Verdana", Font.PLAIN, 32));  // 有默认字体,可以不用设置// 设置类型,纯数字、纯字母、字母数字混合
        captcha.setCharType(Captcha.TYPE_DEFAULT);//缓存验证码
        redisService.set(AuthKeys.AUTH_CAPTCHA, uuid, captcha.text().toLowerCase());// 输出图片流
        captcha.out(response.getOutputStream());}}

3、生成验证码配置

/**
 * 生成验证码配置
 *
 */@ConfigurationpublicclassKaptchaConfig{@BeanpublicDefaultKaptchaproducer(){Properties properties =newProperties();//图片边框
        properties.setProperty("kaptcha.border","no");//文本集合,验证码值从此集合中获取
        properties.setProperty("kaptcha.textproducer.char.string","ABCDEGHJKLMNRSTUWXY23456789");//字体颜色
        properties.setProperty("kaptcha.textproducer.font.color","0,84,144");//干扰颜色
        properties.setProperty("kaptcha.noise.color","0,84,144");//字体大小
        properties.setProperty("kaptcha.textproducer.font.size","30");//背景颜色渐变,开始颜色
        properties.setProperty("kaptcha.background.clear.from","247,255,234");//背景颜色渐变,结束颜色
        properties.setProperty("kaptcha.background.clear.to","247,255,234");//图片宽
        properties.setProperty("kaptcha.image.width","125");//图片高
        properties.setProperty("kaptcha.image.height","35");
        properties.setProperty("kaptcha.session.key","code");//验证码长度
        properties.setProperty("kaptcha.textproducer.char.length","4");//字体
        properties.setProperty("kaptcha.textproducer.font.names","Arial,Courier,cmr10,宋体,楷体,微软雅黑");
        properties.put("kaptcha.textproducer.char.space","5");Config config =newConfig(properties);DefaultKaptcha defaultKaptcha =newDefaultKaptcha();
        defaultKaptcha.setConfig(config);return defaultKaptcha;}}

4、CaptchaService.java接口

publicinterfaceCaptchaService{booleanvalidate(String uuid,String code);BufferedImagegetCaptcha(String uuid);}

5、CaptchaServiceImpl.java实现类

@Service@Slf4jpublicclassCaptchaServiceImplimplementsCaptchaService{@AutowiredprivateProducer producer;@AutowiredprivateRedisService redisService;@Value("${default-captcha}")privateString defaultCaptcha;/**
    * 生成并缓存验证码,返给前端图片
    */@OverridepublicBufferedImagegetCaptcha(String uuid){if(StringUtils.isEmpty(uuid)){thrownewGlobalException(BasicCodeMsg.PARAMETER_ERROR.setMsg("uuid不能为空"));}//生成文字验证码String code = producer.createText();
        log.info("uuid:{},验证码:{}",uuid,code);//缓存验证码
        redisService.set(AuthKeys.AUTH_CAPTCHA, uuid, code);return producer.createImage(code);}}/**
    * 校验验证码
    */@Overridepublicbooleanvalidate(String uuid,String code){//测试环境123456通过验证(可不加)if(EnvEnum.dev.name().equals(env)&& code.equals(defaultCaptcha)){returntrue;}String cacheCode = redisService.get(AuthKeys.AUTH_CAPTCHA, uuid,String.class);if(StringUtils.isEmpty(cacheCode)){returnfalse;}//删除缓存验证码
        redisService.delete(AuthKeys.AUTH_CAPTCHA, uuid);if(cacheCode.equalsIgnoreCase(code)){returntrue;}returnfalse;}

6、增加验证码校验

在登录授权验证的地方添加验证码相关校验,也就是原来校验用户名密码的地方增加。

if("captcha".equals(type)){LoginVo loginVo =LoginVo.builder().captcha(captcha).loginName(username).uuid(uuid).build();boolean result = captchaService.validate(uuid, captcha);if(!result){thrownewOAuth2Exception("验证码不正确");}return;

涉及文件

在这里插入图片描述

标签: java redis spring

本文转载自: https://blog.csdn.net/weixin_47061482/article/details/130060608
版权归原作者 一只IT攻城狮 所有, 如有侵权,请联系我们删除。

“Java实现图片验证码功能”的评论:

还没有评论