本文档介绍如何在 Pig 框架中实现接口防刷验证码功能。命中爬虫和防盗刷规则后,会阻断请求,并生成解除阻断的验证码,验证码有多种组合方式,如果客户端可以正确输入验证码,则可以继续访问。

代码使用

1. 引入依赖

pig-upms-biz 中引入依赖:

<dependency>
    <groupId>com.pig4cloud.plugin</groupId>
    <artifactId>anti-reptile-spring-boot-starter</artifactId>
    <version>0.0.3</version>
</dependency>

2. 配置 Nacos

在 Nacos 配置文件中加入配置:

anti:
  reptile:
    enabled: true
    global-filter-mode: true #开启全局反爬,也可通过注解或配置文件指定需要反爬的接口
    ip-rule:
      request-max-size: 2
spring:
  redisson:
    address: redis://127.0.0.1:6379

3. 配置 Pig-UI 异常拦截

在 pig-ui 的 src/router/axios 的 HTTPresponse 拦截器中添加异常拦截的配置:

// HTTPresponse 拦截
axios.interceptors.response.use(
  res => {
    NProgress.done();
    const status = Number(res.status) || 200;
    const message = res.data.msg || errorCode[status] || errorCode["default"];
    
    // 后台定义 424 针对令牌过去的特殊响应码
    if (status === 424) {
      MessageBox.confirm("令牌状态已过期,请点击重新登录", "系统提示", {
        confirmButtonText: "重新登录",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(() => {
        store.dispatch("LogOut").then(() => {
          // 刷新登录页面,避免多次弹框
          window.location.reload();
        });
      })
        .catch(() => {});
      return;
    }
    
    if (status !== 200 || res.data.code === 1) {
      Message({
        message: message,
        type: "error"
      });
      return Promise.reject(new Error(message));
    }
    
    return res;
  },
  error => {
    // 添加如下配置
    if (error.response.status === 509) {
      const html = error.response.data
      const verifyWindow = window.open('', '_blank', 'height=400,width=560')
      verifyWindow.document.write(html)
      verifyWindow.document.getElementById('baseUrl').value = 'http://localhost:8080/admin'
    }
    NProgress.done();
    return Promise.reject(new Error(error));
  }
);

4. 配置接口权限

在 Nacos 的 application-dev.yml 中添加相应配置,放开验证码回调接口的权限。

配置说明

所有配置均以 anti.reptile 为前缀。

配置项描述默认值示例
enabled是否启用反爬虫插件truetrue
globalFilterMode是否启用全局拦截模式falsetrue
include-urls局部拦截时,需要反爬的接口列表,以’,‘分隔,支持正则匹配。全局拦截模式下无需配置/client,/user,^/admin/.*$
ip-rule.enabled是否启用 IP Ruletruetrue
ip-rule.expiration-time时间窗口长度 (ms)50005000
ip-rule.request-max-size单个时间窗口内,最大请求数2020
ip-rule.lock-expire命中规则后自动解除时间(单位:s)10 天20
ip-rule.ignore-ipIP 白名单,支持后缀’*‘通配,以’,‘分隔192.168.*,127.0.0.1
ua-rule.enabled是否启用 User-Agent Ruletruetrue
ua-rule.allowed-linux是否允许 Linux 系统访问falsefalse
ua-rule.allowed-mobile是否允许移动端设备访问truetrue
ua-rule.allowed-pc是否允许移 PC 设备访问truetrue
ua-rule.allowed-iot是否允许物联网设备访问falsefalse
ua-rule.allowed-proxy是否允许代理访问falsefalse

实现原理

我们引入依赖之后,实际上是通过 Spring Boot 自动装配了 AntiReptileAutoConfig 配置类。该类 Import 了 RedissonAutoConfig 和 WebMvcConfig 两个配置类。

核心组件

  1. ServletRegistrationBean

    • 注册 ValidateFormServlet,拦截 /kk-anti-reptile/validate 路径
    • 处理验证码验证请求
  2. IpRule

    • 实现 IP 级别的反爬规则
    • 支持白名单配置
    • 支持请求频率限制
  3. UaRule

    • 实现 User-Agent 级别的反爬规则
    • 支持设备类型过滤
    • 支持代理检测
  4. VerifyImageUtil

    • 生成验证码图片
    • 管理验证码缓存

User-Agent 是终端的身份标识,服务器可以通过它判断请求来源。某些爬虫可能会伪造 User-Agent,因此需要结合其他规则进行防护。

♥️ 获取支持

遇到问题?

如果您在使用过程中遇到任何问题、有功能建议或需求,请点击此卡片前往 Gitee 仓库提交 Issue。