应在中间件中先校验user-agent非空与长度,再匹配爬虫特征并拦截,返回403或429状态码,ua校验与ip限流应拆分为独立中间件,并注意前置代理导致的header覆盖问题。

如何在Echo中间件里检查User-Agent字符串
直接读取request.Header.Get("User-Agent")是最简单的方式,但别急着写死匹配逻辑。真实场景中,UA字段可能为空、被客户端故意清空、或被代理层篡改。建议先做非空校验和长度限制(比如超过500字符大概率是注入尝试),再进入规则判断。
哪些UA模式该被拦截
不是所有非浏览器UA都要拦——很多监控工具、健康检查探针也用curl或Go-http-client。重点拦截的是明确暴露爬虫意图的特征:
- 包含
Scrapy、python-requests、HeadlessChrome但无Chrome/版本号 - UA值为
mozilla(全小写)、*、-、空格或重复空白符 - 匹配正则
^Mozilla\/5\.0 \(.*?\) AppleWebKit\/.*?Safari\/.*?$但缺失Windows、Macintosh、Linux等OS标识 - UA里带
sqlmap、nuclei、gau等已知安全扫描器关键词
拦截后返回什么状态码更合理
返回403 Forbidden是常规做法,但容易暴露你有主动防御逻辑;对高频试探性请求,用429 Too Many Requests配合X-RateLimit-Remaining头反而更隐蔽,还能自然融入限流系统。注意:不要在响应体里输出“爬虫禁止”之类提示,避免给攻击者反馈。
要不要把UA校验和IP限流耦合
要,但别在同一个中间件里硬编码。推荐拆成两个独立中间件:uaFilterMiddleware只做UA黑白名单+基础格式校验,ipRateLimitMiddleware负责计数与拦截。两者通过c.Get("client_ip")共享IP信息即可。这样既便于单独开关策略,也方便后续把UA规则抽到Redis或配置中心——毕竟UA指纹库会频繁更新,硬编码进Go二进制里太僵硬。
CF-Connecting-IP或X-Forwarded-For,必须确认echo.HTTPErrorHandler捕获的请求对象是否已还原真实Header,否则UA校验永远跑在假数据上。











