应先校验User-Agent非空与长度(如≤500字符),再匹配爬虫特征(Scrapy、sqlmap等)并拦截,单次可疑请求返回403,高频试探返回429;UA校验与IP限流须拆分为独立中间件,且需注意前置代理导致的Header覆盖问题。

怎么用Echo中间件做UA基础拦截
直接在中间件里读 request.Header.Get("User-Agent") 是最简路径,但别跳过校验环节。真实请求中UA可能为空、被客户端清空,或被CDN/Nginx覆盖成 CF-Connecting-IP 这类值。先判断长度是否为0或超过500字符(超长大概率是注入试探),再进正则匹配。
重点拦截这几类:
- 包含 Scrapy、python-requests、HeadlessChrome 但无 Chrome/ 版本号的字符串
- 值为 mozilla(全小写)、*、-、纯空白符
- 匹配 ^Mozilla\/5\.0 \(.*?\) AppleWebKit\/.*?Safari\/.*?$ 却缺失 Windows / Macintosh / Linux 等OS标识
- 含已知扫描器关键词: sqlmap、nuclei、gau
为什么UA校验和IP限流不能写在一个中间件里
硬编码耦合会导致策略无法独立开关、规则更新要重编译、后续难接入Redis动态UA库。应该拆成两个中间件:uaFilterMiddleware 只管UA黑白名单与格式校验,ipRateLimitMiddleware 负责计数与响应头控制,两者通过 c.Get("client_ip") 共享IP信息即可。
这样做的实际好处:
- UA规则可随时从配置中心热加载,不用重启服务
- 测试时能单独关闭UA拦截,只压测限流逻辑
- 日志里能清晰区分是UA拒接还是IP超频
返回403还是429?关键看请求频率
单次可疑UA请求返回 403 Forbidden 没问题;但对高频试探性请求(比如1分钟内10+次带 curl/7.68.0 的请求),用 429 Too Many Requests 更合适——它天然兼容限流系统,还能配合 X-RateLimit-Remaining 头隐藏防御意图。
必须注意:
- 响应体里不要输出“禁止爬虫”“非法访问”之类提示
- 不要在Header里暴露后端框架(如 X-Powered-By: Echo)
- 所有拦截响应都该走统一错误处理器,避免中间件各自写 c.String() 导致状态码混乱
前置代理导致UA失效,怎么确认真实Header
Nginx或CDN转发后,原始 User-Agent 很可能被覆盖。必须检查 echo.HTTPErrorHandler 捕获的 *http.Request 对象是否已还原真实Header。验证方法很简单:在中间件开头加一行日志 log.Printf("UA: %s, RealIP: %s", c.Request().Header.Get("User-Agent"), c.RealIP()),对比Nginx access_log里的原始值。
如果发现不一致:
- 确认Nginx是否配置了 proxy_set_header User-Agent $http_user_agent;
- Echo启动时是否启用 echo.WrapHTTPHandler 或正确配置了 echo.HTTPErrorHandler 的调用链
- 检查 echo.HTTPErrorHandler 是否在 echo.Use() 之后注册,否则中间件早于错误处理逻辑执行
真实部署中最容易被忽略的是Header还原时机——UA校验中间件跑在假数据上,等于没拦。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











