Laravel怎么实现验证码登录_Laravel生成图片验证码功能【插件】

2次阅读

gregwar/captcha仍是laravel图片验证码最稳的选择,因其兼容php 7.4+和laravel 8–11、不强制依赖gd扩展、轻量且持续维护;其他方案多已弃更或要求高版本环境。

Laravel怎么实现验证码登录_Laravel生成图片验证码功能【插件】

为什么 gregwar/captcha 仍是 Laravel 图片验证码最稳的选择

因为它是少数几个仍保持 PHP 7.4+ 兼容、Laravel 8–11 全支持、且不依赖 GD 外部扩展(可退化到 imagick)的轻量方案。其他包要么已弃更,要么强制要求 Laravel 10+ 或 PHP 8.2,上线后容易因环境差异直接报 class 'Captcha' not found

实操建议:

  • composer require gregwar/captcha 安装,别选带 laravel-captcha 后缀的衍生包——它们多数只是封装一层,但维护滞后
  • 发布配置:运行 php artisan vendor:publish --provider="GregwarCaptchaCaptchaServiceProvider",生成 config/captcha.php
  • 如果服务器没装 gd 扩展,确保 config/captcha.php'driver' => 'imagick',否则页面会空白且无错误提示

Laravel 验证码登录时,Captcha::check() 总返回 false 的原因

不是逻辑写错了,大概率是 session 未生效或验证值被截断。这个函数本身不抛异常,失败就静默返回 false,非常难排查。

常见错误现象:

  • 表单提交用 POST 但没带 _Token 字段 → Session 写入失败 → 验证码 session key 为空
  • 前端传的验证码值含空格或大小写混输(如 "Ab3 "),而默认配置 'case_sensitive' => false'Length' => 4 时,后端实际存的是 4 位纯小写,前端多传一位就比对失败
  • 使用 nginx + PHP-FPM 时,fastcgi_buffering off 没配,导致大体积验证码图片响应被截断,浏览器加载失败,用户反复刷新导致 session key 覆盖

验证前务必加一行日志:Log::debug('captcha input: '.request('captcha')); Log::debug('session key: '.session('_captcha_key'));,对比两者是否匹配。

在 Laravel 10+ 中绕过 csrf 验证但保留验证码校验的写法

登录接口常被设为 VerifyCsrfToken 的 except 列表,但这会导致 Captcha::check() 必然失败——因为验证码依赖 session,而 CSRF 被跳过时,Laravel 默认不启动 session。

正确做法是保留 session 启动,只跳过 token 校验:

  • 不要把路由写进 $except,改用中间件组合:Route::post('/login', [LoginController::class, 'login'])->middleware(['throttle:login', 'web']);
  • app/http/Middleware/VerifyCsrfToken.php$except 里只加「不需要 token 的资源路径」,比如 'api/*',但登录是 Web 路由,不该进这里
  • 若必须关闭 CSRF(如对接小程序),手动启动 session:if (session_status() === PHP_SESSION_NONE) { session_start(); },放在 Captcha::check()

验证码图片返回 500 但日志空,怎么快速定位

这种情况八成是字体文件路径不对。gregwar/captcha 默认用 resources/fonts/Roboto-Regular.ttf,但 Laravel 10+ 默认删了 resources/fonts 目录,且不报错,而是 fallback 到系统字体——而 Alpine linux 或某些 docker 镜像根本没装中文字体,GD 渲染时报致命错误,PHP 直接崩。

解决步骤:

  • 确认字体存在:ls -l resources/fonts/Roboto-Regular.ttf,不存在就 mkdir -p resources/fonts && wget https://github.com/googlefonts/roboto/raw/main/fonts/ttf/Roboto-Regular.ttf -O resources/fonts/Roboto-Regular.ttf
  • 检查 config/captcha.php'font' => 'resources/fonts/Roboto-Regular.ttf' 路径是否为绝对路径?应改为 base_path('resources/fonts/Roboto-Regular.ttf')
  • 临时换驱动测试:'driver' => 'session'(仅存 session 不画图),如果这时能过验证,基本锁定是图像渲染问题

字体路径和 session 初始化顺序,是线上最容易被忽略的两个点。

text=ZqhQzanResources