jzaaa / cake-captcha
Session-based image captcha plugin for CakePHP 5
Requires
- php: >=8.2
- ext-gd: *
- ext-mbstring: *
- cakephp/cakephp: ^5.3
- jzaaa/php-simple-captcha: ^3.0.0
Requires (Dev)
- phpunit/phpunit: ^11.5 || ^12.1 || ^13.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
CakePHP 图片验证码插件,支持点击刷新、Session 校验、自定义图片样式和大小写规则。验证码校验成功后自动失效。
版本兼容
| 插件版本 | CakePHP | PHP |
|---|---|---|
| v3 | 5.3+(5.x) | 8.2–8.5 |
| v2 | 4.4+(4.x) | 7.4+ |
| v1 | 3.x | 参见 v1 文档 |
本文介绍 v3 的安装和使用。需要启用 GD(含 FreeType)、mbstring,以及 CakePHP 所需的 intl 等扩展。
安装和启用
通过 Composer 安装:
composer require "jzaaa/cake-captcha:^3.0"
CakePHP 4 项目继续使用:
composer require "jzaaa/cake-captcha:^2.0"
安装后,在应用根目录执行以下命令加载插件:
bin/cake plugin load JZaaa/CakeCaptcha
启用后,默认验证码地址为 /jzaaa/cake-captcha/。
配置
无需额外配置即可使用。需要调整时,在应用中创建 config/captcha.php。以下是自定义样式示例:
<?php return [ 'captcha' => [ 'route' => '/jzaaa/cake-captcha/', 'config' => [ 'width' => 150, 'height' => 52, 'length' => 4, 'charset' => '2346789abcdefghjmnpqrtuxyzABCDEFGHJMNPQRTUXYZ', 'sensitive' => false, 'sessionKey' => 'captcha', 'bgColor' => '#f5f7fb', 'textColor' => '#1f2937', 'lineColor' => '#d6dde8', 'applyEffects' => true, 'applyNoise' => false, 'distort' => false, 'applyPostEffects' => false, 'randomizeFonts' => false, 'maxLinesBehind' => 1, 'maxLinesFront' => 0, ], ], ];
也可以将 captcha 配置放入应用的 config/app.php;如果同时存在 config/captcha.php,插件启动时会加载该文件。
| 配置项 | 说明 |
|---|---|
captcha.route |
验证码图片地址,仅接受 GET 请求 |
width / height |
图片宽度和高度,单位为像素 |
length |
验证码字符数 |
charset |
生成验证码使用的字符集 |
sensitive |
是否区分大小写,默认 false |
sessionKey |
Session 存储键,默认 captcha |
bgColor / textColor / lineColor |
背景、文字和干扰线颜色 |
applyEffects |
干扰效果总开关 |
applyNoise / distort / applyPostEffects |
噪点、图像扭曲和后期效果开关 |
randomizeFonts |
是否为每个字符随机选择字体 |
maxLinesBehind / maxLinesFront |
文字后方、前方的最大干扰线数量 |
除 captcha.route 外,表中的选项均位于 captcha.config 下。完整图像配置见 CaptchaConfigs。构造函数传入的选项优先于全局 captcha.config。
使用自定义 sessionKey 时,生成图片和校验验证码两端必须使用相同的键。
页面显示
在表单模板中添加验证码图片和输入框。图片地址通过反向路由生成,修改 captcha.route 后无需调整模板:
<?php $captchaUrl = $this->Url->build([ 'plugin' => 'JZaaa/CakeCaptcha', 'controller' => 'Captcha', 'action' => 'index', ]); ?> <img src="<?= h($captchaUrl) ?>" alt="验证码,点击刷新" onclick="this.src = this.src.split('?')[0] + '?t=' + Date.now()" style="cursor: pointer;"> <?= $this->Form->control('userCode', ['label' => '验证码', 'autocomplete' => 'off']) ?>
点击图片即可刷新。每次获取图片都会更新当前 Session 中的验证码,请以最新图片为准。
服务端校验
在控制器文件中引入:
use JZaaa\CakeCaptcha\Captcha;
在处理表单提交的 action 中校验,并传入当前请求的 Session:
$userCode = $this->request->getData('userCode'); $captcha = new Captcha([ 'session' => $this->request->getSession(), ]); if (!is_string($userCode) || $userCode === '' || !$captcha->check($userCode)) { // 返回验证码错误,停止处理本次表单。 } else { // 验证成功,继续处理表单;验证码已从 Session 删除。 }
成功后验证码只能使用一次;失败时保留当前验证码,可以重试或刷新图片。sensitive=false 时忽略大小写,true 时严格区分大小写。
验证码接口与表单请求必须使用同一会话。如果验证码用于登录或注册页面,请在应用的认证、授权配置中允许匿名访问验证码地址。
自定义图片输出
如果需要在自己的接口中返回图片或 Base64,可以直接生成验证码:
$captcha = new Captcha([ 'session' => $this->request->getSession(), 'width' => 180, 'height' => 60, ]); $captcha->create(); return $this->response ->withType('jpeg') ->withHeader('Cache-Control', 'no-store') ->withStringBody($captcha->image());
调用 create() 后,可使用以下方法:
| 方法 | 返回内容 |
|---|---|
image() |
JPEG 图片字节,适合写入响应体 |
base64() |
可用于图片 src 的 Base64 data URI |
imgBase64() |
包含 Base64 图片的 <img> 标签 |
img() |
直接输出图片 |
从 v2 升级
- 应用升级到 CakePHP 5.3+、PHP 8.2+;CakePHP 4 项目请继续使用 v2。
- 将 Composer 依赖升级到
^3.0,保留JZaaa/CakeCaptcha加载配置。 - 保留现有
captcha配置以及new Captcha(['session' => ...])、create()、check()调用。 - 若直接引用
JZaaa\CakeCaptcha\Plugin,改为JZaaa\CakeCaptcha\CakeCaptchaPlugin。 - 检查自定义插件控制器扩展:应用 AppController 的组件和回调不再自动继承。
- 只使用配置的验证码地址;旧脚手架生成的
/cake-captcha/...fallback 路由已移除。 sensitive=true现在实际生效。0/o、1/l不再视为相同字符,比较不再进行数字字符串的宽松转换。
更多变更见 CHANGELOG。