springboot登录失败3次后需要验证码的设计及实现
前言:
不用验证码是方便登陆,用验证码是为了防止暴力破解。为了即能满足方便,同时防止暴力破解,需要使用用户登陆失败3次后出现验证码。
1. 登陆失败次数记录, 在login 中查询并记录用户登陆失败次数
WARNING: 无论验证成功还是失败,前端都刷新验证码。后端验证码用一次就失效
- @RequestMapping("/login")
- public Result login(@RequestBody LoginBody loginBody){
- int errorTimes = redis.get(loginBody.getUsername()+"-loginError");
- bool needKaptcha = false;
- if(errorTimes>2){
- needKaptcha = true;
- }
- if(needKaptcha){
- String kaptchaCode = redis.get("kaptcha-"+loginBody.getKaptchaUUID());
- redis.remove("kaptcha-"+loginBody.getKaptchaUUID());//验证码用一次就作废,防止被利用
- if( ! kaptchaCode.equels(loginBody.getKaptchaCode())){
- return Result.error("验证码错误!");
- }
- }
- //to do
- //验证用户账号密码
- if(!userService.login(loginBody)){
- int errorTimes = redis.get(loginBody.getUsername()+"-loginError");
- errorTimes++;
- redis.set(loginBody.getUsername()+"-loginError", errorTimes);
- return Result.error("用户密码错误", errorTimes=errorTimes);
- }
- }
2. 生成验证码
增加依赖
<!-- 验证码 -->
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
- //KaptchaConfig
- @Configuration
- public class KaptchaConfig {
- @Bean
- public Producer kaptchaProducer(){
- Properties properties = new Properties();
- properties.setProperty("kaptcha.image.width","100");
- properties.setProperty("kaptcha.image.height","40");
- properties.setProperty("kaptcha.textproducer.font.size","32");
- properties.setProperty("kaptcha.textproducer.font.color","black");
- properties.setProperty("kaptcha.textproducer.char.string","0123456789QWERTYUIOPASSDFGHJKLZXCVBNM");//文本集合
- properties.setProperty("kaptcha.textproducer.char.length","4");//验证码长度
- properties.setProperty("kaptcha.noise.impl","com.google.code.kaptcha.impl.NoNoise"); //选择哪个干扰类
- DefaultKaptcha kaptcha = new DefaultKaptcha();
- Config config = new Config(properties);
- kaptcha.setConfig(config);
- return kaptcha;
- }
- }
- @GetMapping("/kaptcha")
- public AjaxResult getKaptcha() throws IOException {
- String uuid = UUID.randomUUID().toString();
- //生成验证码
- String text = kaptchaProduce.createText();
- //将验证码保存到redis,有效期5分钟
- redisService.set(RedisKey.getKaptcha("kaptchaUUID-"+uuid),text,5, TimeUnit.MINUTES);
- //将验证码转换为图片
- BufferedImage image = kaptchaProduce.createImage(text);
- // 转换流信息写出
- FastByteArrayOutputStream os = new FastByteArrayOutputStream();
- ImageIO.write(image, "jpg", os);
- Map<String,String> res=new HashMap<>();
- res.put("kaptchaUUID",uuid);
- //res.put("kaptchaCode",text);
- res.put("img", "data:image/jpeg;base64,"+Base64.encode(os.toByteArray()));
- return toAjax(res);
- }
============ 欢迎各位老板打赏~ ===========
与本文相关的文章
- · springboot使用lock4j实现并发控制
- · springboot全局增加sentinel
- · Springboot整合Swagger常用注解
- · swagger隐藏authentication参数
- · Spring Security 中的自定义PreAuthorize 注解
- · JACKSON和FASTJSON处理返回JSON数据中为NULL字段不显示
- · 将数据从mysql迁移到clickhouse
- · Mybatis —— 解决单引号带来的sql注入问题
- · Springboot整合Nacos(动态改变数据库连接参数)
- · springboot访问静态资源404 —-idea设置问题
- · Java基础问题13个,你都会哪些?
- · 不重新打包项目并替换部分jar包