PHP 滑动验证码扩展包教程 适配 Laravel/ThinkPHP 高安全易集成

AI 概述
这是一款高性能安全滑动验证码PHP扩展包,适配PHP8.2+,支持Laravel、ThinkPHP及原生PHP。具备双重验证、防重放、限流防破解能力,界面美观自适应、支持深浅主题。无第三方依赖、轻量化易部署,提供多种前端接入方式与完整配置项、JS API,含三种验证模式,附带详细框架集成教程与生产环境安全使用建议。
目录
文章目录隐藏
  1. 特性
  2. 环境要求
  3. 安装
  4. 快速开始
  5. 配置说明
  6. JavaScript API
  7. 安全建议
  8. 结语

PHP 滑动验证码扩展包教程 适配 Laravel/ThinkPHP 高安全易集成

传统验证码安全性低、体验繁琐,已无法满足现代 Web 项目需求。这款高性能滑动验证码 PHP 扩展包,集安全、轻量、易用于一体,完美兼容 Laravel、ThinkPHP 与原生 PHP,支持双重验证、防重放、防暴力破解,搭配现代化 UI 与响应式设计,只需几步集成,就能为网站登录、表单提交提供稳定高效的安全防护。

特性

  • 高性能:优化的图像处理算法,响应迅速;
  • 高安全性:支持双重验证模式,容错机制、错误次数限制、防暴力破解;
  • 美观界面:现代化 UI 设计,支持浅色/深色主题;
  • 响应式:完美适配各种屏幕尺寸,移动端优化;
  • 易集成:支持 Laravel 11+、ThinkPHP 8+ 等主流框架;
  • 兼容性:支持 PHP 8.2+,不依赖任何第三方包;
  • 轻量化:无外部依赖,安装即用;
  • 防重放:Token一次性使用,防止重放攻击;
  • 易重置:提供reset()接口,表单失败后快速重置。

环境要求

  • PHP >= 8.2;
  • GD 扩展;
  • Laravel 11+ 或 ThinkPHP 8+(可选)。

安装

通过 Composer 安装:

composer require zxf/captcha

快速开始

Laravel 中使用(支持 Laravel 11+)

1. 安装服务提供者(Laravel 11+ 会自动发现)

注意:本包需要 Laravel 11.0 或更高版本。

对于需要手动注册的情况,在 bootstrap/providers.php 中注册服务提供者:

return [
    // ...
    zxf\Captcha\Laravel\CaptchaServiceProvider::class,
];

2. 发布配置文件

php artisan vendor:publish --tag=xf-captcha-config

3. 在 Blade 模板中使用

Laravel 11 中引入 xfCaptcha 有三种方式:

方式一:使用 Blade 组件(推荐)

使用@include引入 Blade 组件,会自动加载 CSS 和 JS 资源:

<!DOCTYPE html>
<html>
<head>
    <title>验证码演示</title>
</head>
<body>
    <form method="POST" action="/login" id="loginForm">
        @csrf

        <!-- 使用 Blade 组件 - 最简单的方式 -->
        @include('xf-captcha::captcha', [
            'selector' => '.xf-captcha',
            'placeholder' => '点击完成验证',
            'inputName' => 'xf_captcha',
        ])

        <div class="xf-captcha"></div>

        <button type="submit">提交</button>
    </form>

    <script>
        // 表单提交示例
        document.getElementById('loginForm').addEventListener('submit', function(e) {
            e.preventDefault();

            fetch('/login', {
                method: 'POST',
                body: new FormData(this)
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    alert('登录成功!');
                    window.location.href = '/dashboard';
                } else {
                    alert('登录失败:' + data.message);
                    // 重置验证码
                    xfCaptcha.reset();
                }
            });
        });
    </script>
</body>
</html>

方式二:手动引入资源(需要自定义时)

如果需要更多自定义控制,可以手动引入 CSS 和 JS:

<!DOCTYPE html>
<html>
<head>
    <title>验证码演示</title>
    <!-- 手动引入 CSS -->
    <link rel="stylesheet" href="{{ route('xf-captcha.css') }}">
</head>
<body>
    <form method="POST" action="/login" id="loginForm">
        @csrf

        <!-- 验证码容器 -->
        <div id="my-captcha"></div>

        <button type="submit">提交</button>
    </form>

    <!-- 手动引入 JS -->
    <script src="{{ route('xf-captcha.js') }}"></script>
    <script>
        // 手动初始化
        xfCaptcha.init({
            handleDom: '#my-captcha',
            getImgUrl: '{{ route('xf-captcha.image') }}',
            checkUrl: '{{ route('xf-captcha.check') }}',
            placeholder: '点击完成验证',
            inputName: 'xf_captcha',
            theme: 'auto'
        });

        // 表单提交
        document.getElementById('loginForm').addEventListener('submit', function(e) {
            e.preventDefault();

            fetch('/login', {
                method: 'POST',
                body: new FormData(this)
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    alert('登录成功!');
                } else {
                    alert('登录失败:' + data.message);
                    xfCaptcha.reset();
                }
            });
        });
    </script>
</body>
</html>

方式三:使用 @stack 和 @push(需要控制资源加载位置时)

如果需要在特定位置(如页面底部)加载 JS,可以使用 @stack:

<!DOCTYPE html>
<html>
<head>
    <title>验证码演示</title>
    <!-- 在头部加载 CSS -->
    <link rel="stylesheet" href="{{ route('xf-captcha.css') }}">
</head>
<body>
    <form method="POST" action="/login" id="loginForm">
        @csrf

        @include('xf-captcha::captcha', [
            'selector' => '.xf-captcha',
            'placeholder' => '点击完成验证',
            'inputName' => 'xf_captcha',
        ])

        <div class="xf-captcha"></div>

        <button type="submit">提交</button>
    </form>

    <!-- 在底部加载所有 JS -->
    @stack('scripts')

    <script>
        // 表单提交逻辑
        document.getElementById('loginForm').addEventListener('submit', function(e) {
            e.preventDefault();
            // ... 提交逻辑
        });
    </script>
</body>
</html>

方式四:使用资源混合(Laravel Mix/Vite)

如果使用 Laravel Mix 或 Vite 构建前端资源:

// resources/js/app.js
import 'zxf/captcha/resources/assets/js/captcha';
import 'zxf/captcha/resources/assets/css/captcha.css';

// 初始化验证码
document.addEventListener('DOMContentLoaded', function() {
    xfCaptcha.init({
        handleDom: '.xf-captcha',
        getImgUrl: '/xf_captcha/image',
        checkUrl: '/xf_captcha/check',
        inputName: 'xf_captcha'
    });
});

然后在 Blade 模板中:

<!DOCTYPE html>
<html>
<head>
    <title>验证码演示</title>
    @vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
    <form method="POST" action="/login">
        @csrf
        <div class="xf-captcha"></div>
        <button type="submit">提交</button>
    </form>
</body>
</html>

4. 后端验证

use Illuminate\Http\Request;

publicfunction login(Request $request)
{
    // 验证请求
    $validated = $request->validate([
        'email' => 'required|email',
        'password' => 'required',
        'xf_captcha' => 'required|xfCaptcha', // 验证验证码
    ], [
        'xf_captcha.required' => '请完成滑动验证',
        'xf_captcha.xf_captcha' => '验证失败,请重新验证',
    ]);
    
    // 登录逻辑...
}

ThinkPHP 中使用(支持 ThinkPHP 8+)

1. 配置

在 config/service.php 中添加:

return [
    // ...
    'services' => [
        zxf\Captcha\ThinkPHP\CaptchaService::class,
    ],
];

2. 发布配置

php think vendor:publish zxf/captcha

3. 在模板中使用

<!DOCTYPE html>
<html>
<head>
    <title>验证码演示</title>
    <link rel="stylesheet" href="/xf_captcha/css">
</head>
<body>
    <form method="POST" action="/login" id="loginForm">
        <div class="xf-captcha"></div>
        <input type="hidden" name="xf_captcha_token" id="xf_captcha_token">
        <button type="submit">提交</button>
    </form>
    
    <script src="/xf_captcha/js"></script>
    <script>
        xfCaptcha.init({
            handleDom: '.xf-captcha',
            getImgUrl: '/xf_captcha/image',
            checkUrl: '/xf_captcha/check',
            inputName: 'xf_captcha_token'
        });
        
        // 表单提交
        document.getElementById('loginForm').addEventListener('submit', function(e) {
            e.preventDefault();
            
            fetch('/login', {
                method: 'POST',
                body: new FormData(this)
            })
            .then(response => response.json())
            .then(data => {
                if (data.code === 200) {
                    alert('登录成功!');
                } else {
                    alert('登录失败:' + data.msg);
                    xfCaptcha.reset(); // 重置验证码
                }
            });
        });
    </script>
</body>
</html>

4. 后端验证

use zxf\Captcha\Captcha;

publicfunction login()
{
    $data = input('post.');
    
    // 验证验证码
    $captcha = app('xfCaptcha');
    $result = $captcha->verify(null, $data['xf_captcha_token'] ?? '');
    
    if (!$result['success']) {
        return json(['code' => 400, 'msg' => $result['message']]);
    }
    
    // 登录逻辑...
}

原生 PHP 中使用

<?php
require_once'vendor/autoload.php';

usezxf\Captcha\Captcha;

session_start();

// 创建验证码实例
$captcha = new Captcha([
    'verify_mode' => Captcha::VERIFY_DUAL, // 双重验证模式
]);

// 生成验证码图片
if ($_GET['action'] === 'image') {
    $captcha->make();
    exit;
}

// 验证
if ($_GET['action'] === 'check') {
    $result = $captcha->verify($_GET['captcha_r'] ?? null, $_GET['xf_captcha_token'] ?? null);
    header('Content-Type: application/json');
    echo json_encode($result);
    exit;
}
?>
<!DOCTYPE html>
<html>
<head>
    <title>验证码演示</title>
    <link rel="stylesheet" href="/path/to/captcha.css">
</head>
<body>
    <form method="POST" action="/submit" id="myForm">
        <div class="xf-captcha"></div>
        <input type="hidden" name="xf_captcha_token" id="xf_captcha_token">
        <button type="submit">提交</button>
    </form>
    
    <script src="/path/to/captcha.js"></script>
    <script>
        xfCaptcha.init({
            handleDom: '.xf-captcha',
            getImgUrl: '?action=image',
            checkUrl: '?action=check',
            inputName: 'xf_captcha_token'
        });
        
        // 表单提交
        document.getElementById('myForm').addEventListener('submit', function(e) {
            e.preventDefault();
            
            fetch('/submit', {
                method: 'POST',
                body: new FormData(this)
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    alert('提交成功!');
                } else {
                    alert('提交失败:' + data.message);
                    xfCaptcha.reset(); // 重置验证码
                }
            });
        });
    </script>
</body>
</html>

配置说明

完整配置示例

<?php
return [
    /*
    |--------------------------------------------------------------------------
    | 滑块图片路径
    |--------------------------------------------------------------------------
    |
    | 自定义滑块图片,留空则使用默认图片
    |
    */
    'slide_dark_img' => '',
    'slide_transparent_img' => '',
    
    /*
    |--------------------------------------------------------------------------
    | 背景图片配置
    |--------------------------------------------------------------------------
    |
    | 可以配置背景图片目录或具体图片路径数组
    |
    */
    'bg_images_dir' => '',
    'bg_images' => [],
    
    /*
    |--------------------------------------------------------------------------
    | 容错像素值
    |--------------------------------------------------------------------------
    |
    | 滑动位置允许的误差范围(像素)
 |
    */
    'fault_tolerance' => 3,
    
    /*
    |--------------------------------------------------------------------------
    | 最大错误次数
    |--------------------------------------------------------------------------
    |
    | 超过此次数后需要刷新验证码
    |
    */
    'max_error_count' => 10,
    
    /*
    |--------------------------------------------------------------------------
    | 图片尺寸
    |--------------------------------------------------------------------------
    */
    'bg_width' => 240,
    'bg_height' => 150,
    'mark_width' => 50,
    'mark_height' => 50,
    
    /*
    |--------------------------------------------------------------------------
    | 输出格式
    |--------------------------------------------------------------------------
    */
    'output_format' => 'webp', // 'webp' 或 'png'
    'webp_quality' => 40,
    'png_quality' => 7,
    
    /*
    |--------------------------------------------------------------------------
    | Session 前缀
    |--------------------------------------------------------------------------
    */
    'session_prefix' => 'xf_captcha',
    
    /*
    |--------------------------------------------------------------------------
    | 资源路由配置
    |--------------------------------------------------------------------------
    */
    'route_prefix' => 'xf_captcha',
    
    /*
    |--------------------------------------------------------------------------
    | 验证模式
    |--------------------------------------------------------------------------
    |
    | frontend_only - 仅前端验证(不安全,仅测试)
    | backend_only  - 仅后端验证
    | dual          - 双重验证(推荐,最安全)
    |
    */
    'verify_mode' => 'dual',
    
    /*
    |--------------------------------------------------------------------------
    | Token 过期时间(秒)
    |--------------------------------------------------------------------------
    */
    'token_expire' => 300,
    
    /*
    |--------------------------------------------------------------------------
    | 前端配置
    |--------------------------------------------------------------------------
    */
    'frontend' => [
        'theme' => 'auto', // 'light' | 'dark' | 'auto'
        'input_name' => 'xf_captcha_token',
        'auto_insert_input' => true,
        'placeholder' => '点击按钮进行验证',
        'slide_text' => '拖动左边滑块完成上方拼图',
        'success_text' => '✓ 验证成功',
        'fail_text' => '验证失败,请重试',
        'show_close' => true,
        'show_refresh' => true,
        'show_ripple' => true,
    ],
];

验证模式说明

1. frontend_only – 仅前端验证(不安全)

仅在前端进行滑动验证,不发送请求到后端。此模式仅用于测试,不推荐在生产环境使用。

2. backend_only – 仅后端验证

传统的验证模式,用户滑动后前端发送位置到后端验证。验证通过后返回成功状态,并立即销毁 session 数据。

3. dual – 双重验证(推荐)

最安全的验证模式,流程如下:

  1. 首次验证:用户滑动滑块,前端发送位置到后端
  2. 生成 Token:后端验证位置正确后,生成一次性 Token 返回
  3. 存储 Token:前端将 Token 存入隐藏输入框
  4. 二次验证:表单提交时,后端验证 Token 有效性
  5. 销毁 Token:Token 一次性使用,验证后立即销毁

安全特性:

  • Token 一次性使用,防止重放攻击
  • Token 有过期时间(默认 5 分钟)
  • 使用 hash_equals 防止时序攻击
  • 首次验证后 session 数据保留,二次验证后销毁

JavaScript API

初始化

xfCaptcha.init({
    handleDom: '.xf-captcha',       // 触发元素选择器
    getImgUrl: '/xf_captcha/image', // 图片接口地址
    checkUrl: '/xf_captcha/check',  // 验证接口地址
    placeholder: '点击按钮进行验证', // 按钮占位文字
    slideText: '拖动左边滑块完成上方拼图', // 滑动提示
    successText: '✓ 验证成功',      // 成功提示
    failText: '验证失败,请重试',    // 失败提示
    showClose: true,                // 显示关闭按钮
    showRefresh: true,              // 显示刷新按钮
    showRipple: true,               // 显示水波纹效果
    theme: 'auto',                  // 主题: 'light' | 'dark' | 'auto'
    inputName: 'xf_captcha_token',  // 隐藏输入框 name
    autoInsertInput: true,          // 自动插入隐藏输入框
});

方法

// 获取验证结果
const isVerified = xfCaptcha.result();

// 获取验证令牌(双重验证模式)
const token = xfCaptcha.getToken();

// 动态切换主题
xfCaptcha.setTheme('dark');

// 刷新验证码
xfCaptcha.refresh();

// 显示/隐藏验证码弹窗
xfCaptcha.show();
xfCaptcha.hide();

// 重置验证码状态(表单提交失败后使用)
xfCaptcha.reset();

事件回调

xfCaptcha.init({
    // ... 配置
})
.onSuccess(function(token) {
    console.log('验证成功,Token:', token);
    // 可以在这里添加自定义逻辑
})
.onFail(function() {
    console.log('验证失败');
    // 验证失败后的处理
})
.onClose(function() {
    console.log('验证码弹窗关闭');
    // 弹窗关闭后的处理
});

表单提交示例

document.getElementById('myForm').addEventListener('submit', function(e) {
    e.preventDefault();
    
    // 检查是否已完成验证
    if (!xfCaptcha.result()) {
        alert('请先完成滑动验证');
        return;
    }
    
    fetch('/submit', {
        method: 'POST',
        body: new FormData(this)
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            alert('提交成功!');
            // 重置表单
            this.reset();
            // 重置验证码
            xfCaptcha.reset();
        } else {
            alert('提交失败:' + data.message);
            // 表单提交失败,重置验证码
            xfCaptcha.reset();
        }
    })
    .catch(error => {
        console.error('Error:', error);
        alert('网络错误,请重试');
        xfCaptcha.reset();
    });
});

安全建议

  1. 使用双重验证模式:生产环境请务必使用dual验证模式;
  2. 启用 HTTPS:防止Token被中间人窃取;
  3. 限制错误次数:合理设置max_error_count防止暴力破解;
  4. 自定义背景图:使用自己的背景图片,增加识别难度;
  5. 调整容错值:根据安全需求调整fault_tolerance
  6. 及时重置:表单提交失败后及时调用xfCaptcha.reset()
  7. Token 过期时间:根据业务需求调整token_expire

结语

这款滑动验证码扩展包凭借无依赖、高性能、高安全的特性,成为 PHP 项目安全验证的优选方案。按照文档完成安装、配置与前后端接入,开启双重验证模式,即可实现体验与安全的平衡。合理配置参数并遵循安全建议,能有效抵御自动化攻击,全面保护网站业务安全稳定运行。

以上关于PHP 滑动验证码扩展包教程 适配 Laravel/ThinkPHP 高安全易集成的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。

「点点赞赏,手留余香」

22

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » PHP 滑动验证码扩展包教程 适配 Laravel/ThinkPHP 高安全易集成

发表回复