商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > ThinkPHP如何防止恶意爬虫_恶意爬虫防御配置【安全】

ThinkPHP如何防止恶意爬虫_恶意爬虫防御配置【安全】

  发布于2026-07-06 阅读(0)

扫一扫,手机访问

先说几个核心判断:单纯靠 User-Agent 白名单防爬虫,在 ThinkPHP 这类框架里基本等于“形同虚设”。UA 这玩意儿,谁都能伪造,拿来当安全屏障,敌人只要照抄几个合法字符串就能轻松绕过。它的正确用法,其实是作为第一道快速过滤——放行那些明显可信的客户端,或者标记一下异常流量,比如 User-Agent 字段是空的、纯数字的、或者里面直接挂着 python-requestscurl 这些标识的请求。仅此而已。

真正的防御链条,需要串起中间件统一过滤、行为特征分析、以及动态验证码触发机制,同时别忘了把 CSRF 令牌这套防护老老实实加上。

中间件做 UA 过滤,别把脏活丢给控制器

很多开发者习惯在控制器里顺手写一句 if (stripos($ua, 'Chrome') !== false) 之类的判断。这不是个好习惯。控制器是处理业务逻辑的地方,不是写流量筛子的。代码复用难、后续升级排查都是坑。

正确的做法是写一个中间件,比如 app/middleware/UserAgentFilter.php,在 handle() 方法里统一处理。有几个细节值得注意:

  • 取值要用 request()->header('user-agent'),这是 ThinkPHP 6+ 推荐的方式。别直接去读 $_SERVER['HTTP_USER_AGENT'],否则在 Swoole 或 FastCGI 模式下,这个变量可能为空,坑你没商量。
  • 白名单配置建议放在 app/extra/spider.php 这类配置文件中,比如 return ['Mobile Safari', 'Chrome', 'WeChat'];。千万别在中间件里硬编码,也别去查数据库——首字节响应时间经不起这种折腾。
  • 匹配方式务必用 stripos(),而不是 == 或者正则全匹配。合法的 User-Agent 变体太多了,iPhone 和 iPad 的 UA 除了平台字段不同,其他几乎一样,你很难写个精确匹配覆盖所有情况。
  • 对那些空字符串、纯数字(比如 123456),或者 UA 里带着 curlhttpiepython-requests 的请求,建议记录日志并触发限流。但别一刀切直接用 halt() 打死,误伤正常用户的代价可能更大。

UA 白名单不能当安全屏障,这是常识

说白了,User-Agent 就是一个 HTTP 头,客户端想怎么写就怎么写。Scrapy、Playwright、Requests 这些工具,默认就会随机生成 UA,甚至能完美复刻最新版 Chrome 的 User-Agent。你加的白名单,敌人只要照抄一行字符串就能绕过。

  • 试试这条命令:curl -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"。瞧瞧,你的“UA 白名单”是不是直接被打穿了?
  • 真正该盯住的,是那些 UA 看起来合法,但行为明显异常的请求:没有 Cookie、没有 RefererX-Requested-With 字段为空、或者缺少 JS 行为相关的字段。举个例子,一个请求从页面加载到点击某个按钮的间隔,如果小于 800 毫秒,基本可以断定是脚本模拟的。
  • 检查一下 request()->cookie('thinkphp_token') 是否存在且未过期。真实的用户访问,通常会带着会话标识;而绝大多数爬虫,连维护一个 Cookie jar 都懒得做。

验证码触发点,别只卡在“提交”那个按钮上

人机对抗这件事,难点不是“要不要加验证码”,而是“在哪个环节加、对谁加”。ThinkPHP 自带的 captcha 扩展,只提供了生成和验证的函数,它不会替你决定什么时候该弹验证码。

可行的思路是这样:

  • 首次访问页面时,通过 Ja vaScript 注入一个隐藏字段,比如 _ts(时间戳)。服务端收到请求后,比对 request()->post('_ts') 和当前时间的差值。如果小于 800 毫秒,基本可以判定是脚本在提交。
  • 对于高风险动作,比如登录、注册、批量导出数据,要做前置的风险评分。根据评分结果,动态决定是否需要弹验证码,而不是固定路径强制触发。
  • 验证码不应该只和“提交按钮”绑定。更合理的做法是,从页面加载那一刻起,就开始收集用户的行为信号。比如鼠标轨迹、页面停留时间、滚动行为等等。这些数据比一个简单的验证码要可靠得多。

CSRF 防护,不能光靠文档说“开启”

表单防恶意提交,光指望 UA 或者 Referer 是不靠谱的。ThinkPHP 的 CSRF 防护依赖令牌机制,而且必须显式启用,效果才会到位。

  • 在模板中使用 @csrf 指令,它会自动生成 。这是基础操作。
  • 确保应用已经开启了框架自带的 CSRF 中间件。默认情况下,ThinkPHP 6 是开启的,但如果你自定义了路由,或者对 API 分组做了特殊配置,有可能这个中间件被绕过去了。需要手动检查并确认。
  • 这里有个容易忽略的点:单纯的 POST 请求并不等于“安全”。攻击者照样可以伪造一个 POST 请求,并且带上合法的 token。所以,token 的生成和验证必须绑定 session + 时间戳 + 随机因子,确保每个 token 都是唯一的、一次性的、有有效期的。

ThinkPHP如何防止恶意爬虫_恶意爬虫防御配置【安全】

说到底,UA 白名单一旦写死,反而容易成为攻击者的路标——他们只需要绕开那几个关键词就行。而验证码,如果只在提交时刻才校验,等于你把门锁装在了用户已经进门之后。真正的防御,是一套组合拳:从请求进门的第一道过滤,到行为层面的持续分析,再到关键环节的动态验证。缺一环,效果都会大打折扣。

本文转载于:https://www.php.cn/faq/2436735.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注