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

网友投稿 955 2022-11-02

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

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

背景

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

Kaptcha 框架介绍

⾕歌开源的⼀个可高度配置的实⽤验证码生成⼯具

验证码的字体/大小/颜⾊验证码内容的范围(数字,字⺟,中⽂汉字!)验证码图⽚的大小,边框,边框粗细,边框颜⾊验证码的⼲扰线 验证码的样式(鱼眼样式、3D、普通 模糊)

添加依赖

com.baomidou

kaptcha-spring-bootstarter

1.0.0

配置类

/**

* 图像验证码的配置文件

* @author : look-word

* @date : 2022-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) {

java.security.MessageDigest md =

MessageDigest.getInstance("MD5");

byte[] array =

wTCMXK md.digest(data.getBytes("UTF-8"));

StringBuilder sb = new

StringBuilder();

for (byte item : array) {

sb.append(Integer.toHexString((item & 0xFF) |

0x100)wTCMXK.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

结果

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:时间格式里,sss与SSS的区别
下一篇:Maghead 一个专为PHP7设计的最快对象关系映射(ORM)框架
相关文章

 发表评论

暂时没有评论,来抢沙发吧~