验证码作为防御自动化攻击的“得力小助手”,能有效拦住机器人和恶意脚本的捣乱。今天这篇文章,就手把手教大家在Spring Boot框架的Auth模块里,接入超实用的anji-captcha滑动验证码功能,从配置、实现接口到融入认证流程,每一步都安排得明明白白!

一、配置验证码服务

咱要接入验证码,得先有个能生成和验证它的服务类。这里,咱们用超好用的anji-captcha库,再借助Spring的@Bean注解,把它“送”到IoC容器里,这样后续就能随时用啦。

@Bean public CaptchaService captchaService() { // 创建配置属性对象 Properties config = new Properties(); // 使用Redis作为验证码的缓存,这样能避免内存占用太多,还能在分布式环境里正常工作 config.put(Const.CAPTCHA_CACHETYPE, "redis"); // 去掉验证码上的水印,如果想加的话也能自定义内容 config.put(Const.CAPTCHA_WATER_MARK, ""); // 设置验证码类型为滑动拼图验证码,要是想用别的类型也能改 config.put(Const.CAPTCHA_TYPE, CaptchaTypeEnum.BLOCKPUZZLE.getCodeValue()); // 这是个可选配置,用来指定拼图图片放哪儿,不写的话就用默认图片 // config.put(Const.ORIGINAL_PATH_JIGSAW, FileUtil.getAbsolutePath("classpath:captcha")); // 通过工厂模式,根据配置创建验证码服务实例 return CaptchaServiceFactory.getInstance(config); } 

这里的配置参数都很关键:

  • CAPTCHA_CACHETYPE:决定了验证码的缓存类型,选Redis是因为它能让验证码在分布式场景里稳定存储,还不咋占内存。
  • CAPTCHA_WATER_MARK:就是控制水印的,空着就是没水印,要是有特殊需求,比如加上公司logo啥的,就可以自定义。
  • CAPTCHA_TYPE:能选择各种验证码类型,这次咱用的是滑动拼图验证码,要是想换成像点击特定图片那种,改这里就行。
  • ORIGINAL_PATH_JIGSAW:这个参数可写可不写,写了就能指定拼图图片的存放路径,不写就用默认的图片。

CaptchaServiceFactory.getInstance(config)用的是工厂模式,它能根据咱们设置的配置,自动创建合适的验证码服务实例,然后注册成Spring Bean,要用的时候直接“拿”来用就好。

二、实现验证码控制器

验证码有俩核心功能,生成和验证,咱们就通过CaptchaController这个类来实现对应的接口。其实,CaptchaService这个实例是anji-captcha包里自带的,咱们不用自己再写一套校验逻辑,在配置里设置好验证码类型和缓存来源,在控制器里调用就行。

@RestController @RequestMapping("/ua/captcha") @Api(tags = "验证码") public class CaptchaController { // 通过依赖注入,把CaptchaService引入到控制器里 private final CaptchaService captchaService; public CaptchaController(CaptchaService captchaService) { this.captchaService = captchaService; } // 处理生成验证码的请求 @PostMapping("/get") public ServerResponseEntity<ResponseModel> get(@RequestBody CaptchaVO captchaVO) { // 调用CaptchaService的get方法生成验证码,并返回结果 return ServerResponseEntity.success(captchaService.get(captchaVO)); } // 处理验证验证码的请求 @PostMapping("/check") public ServerResponseEntity<ResponseModel> check(@RequestBody CaptchaVO captchaVO) { // 调用CaptchaService的check方法验证验证码,并返回结果 return ServerResponseEntity.success(captchaService.check(captchaVO)); } } 

这里面的门道也不少:

  • 依赖注入:通过构造函数把CaptchaService注入进来,这样控制器就能调用它的各种方法啦。
  • 接口设计
    • /get接口:专门用来生成验证码,会返回拼图图片,还有像背景图、拼图块这些相关数据。
    • /check接口:用来验证用户滑动的结果,比如拼图坐标对不对,然后返回验证成不成功。
  • 请求与响应
    • 请求体用CaptchaVO来装前端传过来的参数,像验证码ID、滑动坐标这些。
    • 响应的时候,用ServerResponseEntity包装ResponseModel,统一返回格式,这样前后端交互起来就特别方便。
  • 注解说明
    • @RestController:这是告诉程序,这个类是个RESTful风格的控制器,返回的数据都是JSON格式的。
    • @RequestMapping("/ua/captcha"):给验证码相关的接口统一设置了一个路径前缀,方便管理。
    • @Api(tags = "验证码"):这是Swagger的注解,能自动生成API文档,开发和测试的时候就很方便查看接口信息。

三、定义验证码DTO

为了让验证码能在认证流程里“工作”,咱们得定义一个数据传输对象,也就是DTO。这个CaptchaAuthenticationDTO能把验证码的验证结果和认证参数“绑”在一起。

public class CaptchaAuthenticationDTO extends AuthenticationDTO { // 这个字段用来存验证码验证结果,前端调用/check接口后返回的验证令牌就存这儿 @ApiModelProperty(value = "验证码", required = true) private String captchaVerification; // 获取验证码验证结果 public String getCaptchaVerification() { return captchaVerification; } // 设置验证码验证结果 public void setCaptchaVerification(String captchaVerification) { this.captchaVerification = captchaVerification; } // 重写toString方法,方便打印对象信息 @Override public String toString() { return "CaptchaAuthenticationDTO{" + "captchaVerification='" + captchaVerification + ''' + "} " + super.toString(); } } 

这里要注意:

  • 继承AuthenticationDTOCaptchaAuthenticationDTO继承了基础认证DTO,这样既能复用原来的认证字段,比如用户名、密码,又能扩展出验证码字段,代码的复用性和扩展性都很强。
  • 字段定义captchaVerification专门用来存验证码验证结果,一般是前端验证完后传过来的验证令牌。
  • Swagger注解@ApiModelProperty是Swagger的注解,给字段加了描述,生成API文档的时候就能看到每个字段是干啥的了。

四、集成到认证流程

(一)前端调用

  1. 用户一打开登录页面,前端就赶紧调用/ua/captcha/get接口,把滑动验证码“请”出来。
  2. 用户滑动完成后,前端再调用/ua/captcha/check接口验证结果,拿到captchaVerification这个验证令牌。

(二)后端验证

  1. 在认证接口,比如登录接口里,接收CaptchaAuthenticationDTO对象,里面就带着用户名、密码和验证码验证结果这些信息。
  2. 仔细检查captchaVerification是不是有效,如果无效,那就别往下走了,直接返回认证失败的提示。
@PostMapping("/login") public ServerResponseEntity login(@RequestBody CaptchaAuthenticationDTO dto) { // 调用captchaService的verification方法,验证验证码 ResponseModel response = captchaService.verification(dto.getCaptchaVerification()); // 如果验证没通过 if (!response.isSuccess()) { // 返回验证码验证失败的提示 return ServerResponseEntity.fail("验证码验证失败"); } // 验证码通过了,接着走用户名密码认证的逻辑 return ServerResponseEntity.success("登录成功"); } 

五、总结

到这儿,咱们就成功在Auth模块里接入滑动验证码啦!关键步骤再给大家捋一遍:

  • @Bean配置验证码服务,各种类型随便选,超灵活。
  • CaptchaController把生成和验证接口都准备好了,用起来超方便。
  • 定义CaptchaAuthenticationDTO,让验证码能顺利融入认证流程。
  • 在认证逻辑里严格验证验证码结果,给应用安全再加道“锁”。

希望这篇文章能帮到大家,要是在接入过程中有啥问题,欢迎在评论区留言交流!