开发实战|第二篇:基于kaptcha实现验证码

本次分享使用captcha进行验证码生成,虽然本次分享为验证码生成,但仍然涉及到许多知识点,其中包括springboot项目搭建,引入MybatisPlus,lombok插件,时间计算插件joda-time

1.环境搭建

  • 创建SpringBoot项目,引入springBoot环境相关依赖

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.8.RELEASE</version>
    </parent>
    
  • 引入数据库依赖,连接池,lombok,joda-time,http等相关依赖

    <!--引入lombok依赖-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.10</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.1.20</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.16</version>
    </dependency>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.2.0</version>
        <exclusions>
            <exclusion>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-generator</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>joda-time</groupId>
        <artifactId>joda-time</artifactId>
        <version>2.9.9</version>
    </dependency>
    <dependency>
        <groupId>com.qcloud</groupId>
        <artifactId>cos_api</artifactId>
        <version>4.4</version>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.6</version>
    </dependency>
    
  • 引入验证码所需依赖kaptcha

    <!--引入验证码依赖-->
    <dependency>
        <groupId>com.github.axet</groupId>
        <artifactId>kaptcha</artifactId>
        <version>0.0.9</version>
    </dependency>
    
  • 配置数据库连接

    server:
      port: 8082
    
    spring:
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        druid:
          url: jdbc:mysql://192.168.1.100:3306/study
          username: root
          password: root
    

2.验证码实现

  • 验证码配置
@Configuration
public class KaptchaConfig {

  @Bean
  public DefaultKaptcha producer(){
    Properties properties = new Properties();
    properties.put("kaptcha.border", "no");
    properties.put("kaptcha.textproducer.font.color", "black");
    properties.put("kaptcha.textproducer.char.space", "5");
    properties.put("kaptcha.textproducer.font.names", "Arial,Courier,cmr10,宋体,楷体,微软雅黑");
    Config config = new Config(properties);
    DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
    defaultKaptcha.setConfig(config);
    return defaultKaptcha;
  }
}
  • 验证码实体
@TableName("sys_captcha")
@Data
public class SyscaptchaEntity {

  @TableId(type = IdType.INPUT)
  private String uuid;
  /**
   * 验证码
   */
  private String code;
  /**
   * 过期时间
   */
  private Date expireTime;

}
  • 验证码dao
@Mapper
public interface SyscaptchaDao extends BaseMapper<SyscaptchaEntity> {

}
  • 验证码实现主要逻辑
@Service
public class SyscaptchaServiceImpl extends ServiceImpl<SyscaptchaDao, SyscaptchaEntity> implements
    SyscaptchaService {

  @Resource
  private Producer producer;

  @Override
  public BufferedImage getCaptcha(String uuid) {
    if (StringUtils.isEmpty(uuid)) {
      throw new RRException("uuid不能为空");
    }
    //获取验证码
    String code = producer.createText();
    SyscaptchaEntity syscaptchaEntity = new SyscaptchaEntity();
    syscaptchaEntity.setUuid(uuid);
    syscaptchaEntity.setCode(code);
    //从现在开始五分钟后过期
    syscaptchaEntity.setExpireTime(DateUtils.addDateMinutes(new Date(), 5));
    this.saveOrUpdate(syscaptchaEntity);
    return producer.createImage(code);
  }

  @Override
  public boolean validate(String uuid, String code) {
    //根据uuid查询验证码
    SyscaptchaEntity syscaptchaEntity = this.getOne(new QueryWrapper<SyscaptchaEntity>().eq("uuid", uuid));
    //验证码不存在,校验不通过
    if(Objects.isNull(syscaptchaEntity)){
      return false;
    }
    //删除数据库验证码
    this.removeById(uuid);
    //验证码相同,且过期时间大于当前时间,则表示在有效期内
    if(syscaptchaEntity.getCode().equalsIgnoreCase(code) && syscaptchaEntity.getExpireTime().getTime()>= System.currentTimeMillis()){
      return true;
    }
    return false;
  }
}
  • 实现controller
@RestController
public class SyscaptchaController {

  @Resource
  private SyscaptchaService syscaptchaService;

  @GetMapping("/captcha")
  public void get(@RequestParam("uuid") String uuid, HttpServletResponse response) throws IOException {
    response.setHeader("Cache-Control", "no-store,no-cache");
    response.setContentType("image/jpeg");
    BufferedImage image = syscaptchaService.getCaptcha(uuid);
    ServletOutputStream outputStream = response.getOutputStream();
    ImageIO.write(image, "jpg", outputStream);
    IOUtils.closeQuietly(outputStream);
  }

  @GetMapping("/validate")
  public R validate(@RequestParam("uuid") String uuid, @RequestParam("code") String code) {
    boolean validate = syscaptchaService.validate(uuid, code);
    return R.ok().put("validate",validate);
  }

}

本次分享还涉及两个工具类,DateUtilsRRException,Result三个辅助类,由于篇副有限就不在此展示,至此验证码生成主要逻辑已经实现,进行测试查看数据库及返回值如下:

  • 请求返回

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NVmPsROd-1570505142373)(/home/zycao/.config/Typora/typora-user-images/1570504857768.png)]

  • 查看数据库

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-afvDCONx-1570505142374)(/home/zycao/.config/Typora/typora-user-images/1570504894897.png)]

  • 校验返回

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TAKWf7XX-1570505142374)(/home/zycao/.config/Typora/typora-user-images/1570504929483.png)]

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值