极验行为验证插件
极验行为验证(Geetest)
版本:1.0.0 | 作者:怪咖先生 | 对接极验行为验证 4.0 | 适用于 Zsens Admin 3.0+(PHP 8.1+)
一、插件简介
对接极验官方「行为验证 4.0」的验证码插件。前端由极验 SDK 渲染验证组件,用户通过后由本插件服务端携带 captchaId 与私钥向极验二次校验接口发起验签请求,确认真实验证结果后才放行社区业务。
开启后自动接管社区前台登录/注册/找回、发帖、回帖等场景,无需修改社区模板。
官方文档:
- Web API:https://docs.geetest.com/gt4/apirefer/api/web
- 服务端 API:https://docs.geetest.com/gt4/apirefer/api/server
二、功能特性
| 特性 | 说明 |
|---|---|
| 极验官方验证 | 直接使用极验 4.0 SDK,验证能力由极验提供 |
| 服务端二次校验 | HMAC-SHA256 签名后调用 /validate,防止前端绕过 |
| 弹出式滑动验证 | 点击按钮弹出极验滑动窗口,与官网样式一致 |
| 场景独立开关 | 登录/注册/找回、发帖、回帖可分别启用 |
| 一次性票据 | 验证凭据换取一次性票据,消费即失效,防重放 |
| 异常降级 | 极验接口超时或不可用时可按配置放行,避免业务中断 |
| 模板零侵入 | 兼容社区 PJAX 软跳转与动态插入表单 |
| 后台统计 | 通过率趋势、拦截原因 TOP、验证日志 |
三、环境要求
| 项目 | 要求 |
|---|---|
| Zsens Admin | 3.0+ |
| PHP | 8.1+(推荐 8.2+) |
| PHP 扩展 | curl 推荐开启(未开启时回退 filegetcontents) |
| 网络 | 服务器需可访问 static.geetest.com 与 gcaptcha4.geetest.com |
| 极验账号 | 需在极验后台创建「行为验证 4.0」应用,获取 captchaId 与私钥 |
| 社区插件 | 必须安装并启用(community) |
四、接入步骤
4.1 获取极验密钥
- 登录极验后台 https://console.geetest.com/
- 进入 行为验证 4.0,创建或进入应用
- 在应用详情页复制 captchaId(验证 ID) 与 captchaKey(私钥)
- 在同一页面确认域名白名单已包含你的站点域名,否则前端会报配置错误
4.2 安装插件
- 将
Geetest目录整体放入项目plugins/下 - 进入后台 应用中心,找到「极验验证」,点击 安装
- 安装时自动创建
geetest_log日志表、注册后台菜单、复制static/到public/static/Geetest/
4.3 填写配置
进入 应用中心 → 极验验证 → 配置,至少填写:
极验 captchaId:极验后台的验证 ID极验私钥 captchaKey:极验后台的私钥
未填写这两项时,前台不会注入验证码,避免出现无法完成的验证。
4.4 验证接入
- 打开社区前台登录页,应看到极验验证按钮
- 点击按钮弹出滑动验证窗口,按提示完成验证
- 验证通过后控件显示「已通过验证」
- 提交登录,正常进入账号
- 进入 应用中心 → 极验验证 查看日志,应出现一条
result=1、http_code=200的记录
五、后台配置
| 配置项 | 键名 | 默认值 | 说明 |
|---|---|---|---|
| 启用插件 | enabled | 开启 | 总开关,关闭后回退原图形验证码 |
| 登录/注册/找回验证 | userauthenabled | 开启 | 三个账号场景共用 |
| 发帖验证 | userpostenabled | 关闭 | 发布/编辑主题 |
| 回帖验证 | userreplyenabled | 关闭 | 回复主题 |
| 极验 captchaId | captcha_id | 空 | 必填,极验后台获取 |
| 极验私钥 | captcha_key | 空 | 必填,仅服务端使用 |
| 极验 API 域名 | api_server | gcaptcha4.geetest.com | 国内默认;特殊网络环境可改 |
| 接口超时 | timeout | 5000 | 毫秒,1000-15000 |
| 异常时放行 | fail_open | 开启 | 极验接口异常时是否允许通过 |
| 主题色 | theme_color | #2563eb | 用于宿主页面配色 |
六、技术实现
6.1 验证流程
sequenceDiagram
participant U as 用户
participant P as 页面
participant G as 极验服务
participant S as 本插件
participant C as 社区后端
P->>G: 加载 gt4.js 并初始化
U->>G: 完成行为验证
G-->>P: lot_number / captcha_output / pass_token / gen_time
P->>S: POST /geetest/verify 登记凭据
S-->>P: 返回一次性票据 ticket
P->>C: 提交表单,captcha_token=ticket
C->>S: 调用 CaptchaService::checkUser
S->>G: POST /validate(含 sign_token)
G-->>S: result=success / fail
S-->>C: 放行或拒绝6.2 签名算法
按极验规范,使用私钥对流水号做 HMAC-SHA256:
sign_token = HMAC-SHA256(key = captchaKey, message = lot_number)6.3 二次校验请求
POST https://gcaptcha4.geetest.com/validate?captcha_id=<captchaId>
lot_number=<流水号>
captcha_output=<验证输出>
pass_token=<通过标识>
gen_time=<时间戳>
sign_token=<签名>成功响应:
{"result":"success","reason":"","captcha_args":{"used_type":"slide","user_ip":"127.0.0.1"}}失败响应:
{"result":"fail","reason":"pass_token expire"}异常响应:
{"status":"error","code":"-50005","msg":"illegal gen_time"}6.4 字段约定
社区表单只认 captcha 与 captcha_token 两个字段,插件映射如下:
| 社区字段 | 极验模式下的含义 |
|---|---|
captcha_token | 本插件签发的一次性票据 |
captcha | 固定值 1,作为已通过标记 |
极验返回的四个字段暂存在缓存,票据被消费时才发起真实二次校验。
6.5 接口
| 方法 | 地址 | 说明 |
|---|---|---|
| POST | /geetest/verify | 登记极验凭据,返回一次性票据 |
请求字段:lotnumber、captchaoutput、passtoken、gentime、scene。
响应示例:
{"code":1,"msg":"ok","data":{"ticket":"94dc44ab60033516509aa473241a46e1"}}七、异常与降级
| 情况 | fail_open=1(默认) | fail_open=0 |
|---|---|---|
极验返回 result=success | 放行 | 放行 |
极验返回 result=fail | 拒绝 | 拒绝 |
极验返回 status=error | 放行并记录降级 | 拒绝 |
| 网络超时或不可达 | 放行并记录降级 | 拒绝 |
| 未配置 captchaId/私钥 | 放行并记录降级 | 拒绝 |
开启放行时,前台不注入验证码,用户可直接提交;后台日志会以 fail_open: 前缀标记这类记录,并在「降级」列显示标识。
如果站点对安全要求极高,建议关闭放行并自行做好接口可用性监控。
八、安全机制
| 机制 | 说明 |
|---|---|
| 服务端验签 | 私钥只在服务端使用,签名由服务端生成 |
| 票据随机 | random_bytes(16) 生成 32 位十六进制 |
| 一次性消费 | 先删除票据再校验,防并发重放 |
| 票据有效期 | 10 分钟,超时自动失效 |
| 私钥不外泄 | 私钥不出现在任何前台响应中 |
| 防缓存 | 接口响应携带 no-store、no-cache |
极验会自行校验 pass_token 是否过期、是否被复用,因此即使票据被截获,也无法无限次使用。
九、后台管理页
后台路径:应用中心 → 极验验证
- 总验证次数、总通过率、今日验证量、今日通过率
- 近 7 天通过/拦截趋势
- 拦截原因 TOP 排行
- 验证日志:时间、场景、结果、原因、验证类型、流水号、HTTP 状态码、降级标识、IP
- 支持按结果与关键词(IP、原因、流水号)筛选,可清空日志
十、常见问题
Q1:前台没有出现极验验证?
- 确认
captchaId与私钥都已填写并保存 - 确认插件总开关与对应场景开关已开启
- 确认社区插件已安装并启用
- 检查
public/static/Geetest/geetest.js是否存在 - 浏览器控制台查看是否有
gt4.js加载失败
Q2:控制台提示「用户配置错误」或 60000 错误码?
极验后端校验了域名白名单。请到极验后台确认站点域名已加入白名单,且 captchaId 与当前站点匹配。
Q3:后台日志出现「极验异常降级放行」?
说明极验接口调用失败。检查服务器能否访问 gcaptcha4.geetest.com,检查 api_server 配置是否正确,检查超时时间是否过短。若日志中 HTTP 列为 0,通常是网络不通或 DNS 解析失败。
Q4:日志中原因显示「sign error」?
私钥与 captchaId 不匹配。请核对极验后台的私钥是否复制完整(注意首尾空格)。
Q5:为什么有时只需点击按钮,没有出现滑动拼图?
这是极验的正常策略。极验 4.0 先用 AI 行为模型判定风险,绝大多数真实用户点击一次即可通过;被判定存在风险时才进入滑动拼图等二级验证。「弹出式」只决定弹窗形式,不决定验证难度。
Q6:验证组件是什么展现形式?
固定为弹出式 popup:点击按钮弹出滑动窗口,与极验官网一致。展现形式与界面语言不再提供配置项,统一使用推荐值(简体中文)。
Q7:关闭插件后表单提交提示验证码错误?
关闭总开关会回退到原图形验证码。若原插件未启用,请开启它或重新启用本插件。
十一、目录结构
plugins/Geetest/
├── controller/
│ ├── Front.php 前台接口(登记凭据换票据)
│ └── admin/Index.php 后台管理(日志 / 统计 / 清空)
├── compat/
│ └── captcha/service/CaptchaService.php 社区兼容桥接
├── service/
│ ├── GeetestClient.php 极验二次校验客户端与签名
│ ├── GeetestService.php 票据管理、校验编排、日志
│ └── GeetestStore.php 日志表与统计
├── static/
│ ├── geetest.css 前台适配样式
│ └── geetest.js 极验 SDK 初始化与表单联动
├── view/admin/index.html 后台管理页
├── GeetestPlugin.php 插件入口、配置、菜单
├── plugin.json 插件元数据
├── routes.php 路由注册
├── icon.svg 插件图标
└── README.md 使用文档十二、更新日志
详细变更记录见 [CHANGELOG.md](CHANGELOG.md)。
1.0.0
- 对接极验行为验证 4.0 官方 API,HMAC-SHA256 签名二次校验,一次性票据机制
- 移除本地滑动拼图实现