ThinkPHP5验证码安全需五步实操:启用并强制校验、自定义过期时间与密钥、禁用默认admin入口并重映射路由、随机化入口文件名、联动行为风控。

ThinkPHP5 验证码本身不是“隐藏”功能,但它和后台入口安全是强关联的一环。真正让安全翻倍的,是把验证码作为第一道动态防线,配合后台路径隐藏策略一起用。下面这5个功能不靠花哨配置,全是项目上线前必须检查、一加就见效的实操点。
开启并强制校验验证码
默认状态下,TP5 的验证码是关闭的。光装了 think-captcha 扩展还不够,必须主动启用。
- 在 application/config.php 底部找到
login_captcha,设为true - 登录控制器中,在接收 POST 数据前,必须调用
captcha_check()校验,不能只靠前端展示 - 示例代码:
if (!captcha_check(input('captcha'))) $this->error('验证码错误');
自定义验证码过期时间与加密 Key
默认 180 秒 + 默认密钥,等于把锁芯图纸贴在门上。攻击者只要拿到一次 session,就能反复重放。
- 在 config.php 的
captcha配置块里,显式设置'expire' => 120(建议 90–150 秒) - 务必修改
'key' => 'your_custom_secret_string_here',长度建议 16 位以上,避免使用项目名或日期 - Key 一旦设定,就不能随意改,否则旧验证码全部失效——所以首次上线就要定好
禁用默认 admin 入口 + 路由重映射
验证码再强,也挡不住攻击者直接爆破 /admin/login。必须让它“不存在”。
立即学习“PHP免费学习笔记(深入)”;
- 在 config.php 中添加
'deny_module_list' => ['common', 'admin'],禁止访问 admin 模块 - 在 route.php 中定义新路由:
Route::rule('secure-login', 'admin/Login/index'); - 用户只能通过
/secure-login进入,原/admin/*地址返回 404,不跳转、不提示
入口文件随机化(适合轻量部署)
没有 Nginx 重写权限?那就换把“物理钥匙”。
- 复制 public/admin.php,重命名为类似
public/panel_8Xk2mQzR.php的长随机名 - 确保原
admin.php已删除或重命名,服务器不再响应/admin.php - 登录地址变为
https://yoursite.com/panel_8Xk2mQzR.php,且该文件名应仅你和运维知晓
验证码联动登录行为风控
单纯图形验证已不够。把验证码变成“行为开关”,让异常访问自动触发拦截。
- 连续 3 次验证码失败后,在 session 或缓存中记录 IP+时间戳,后续请求强制要求输入更复杂验证码(如 6 位+中文)
- 非工作时段(如凌晨 2–5 点)访问登录页,自动返回带干扰线、低对比度的验证码图片
- 结合
input('server.HTTP_USER_AGENT')初筛:空 UA、明显爬虫 UA 直接拒绝返回验证码资源



















