php实现前后端三维图形人机验证代码

代码语言:php

所属分类:验证码

代码描述:php实现前后端三维图形人机验证代码,前端只收形状渲染数据,不含答案与极值信息,调 JS 无法伪造通过 题目 120s 过期、反应 < 800ms 判为机器、每题限 3 次,用尽自动换题 token 一次性、5 分钟有效,登录校验后立即销毁,防重放 换题限流:60s 内 ≤ 20 次,防暴力枚举答案

代码标签: php 前后端 三维 图形 人机 验证 代码

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<?php
/**
 * ShapeGuard · 3D 几何体人机验证 —— PHP 7.2 单文件前后端实现
 * ----------------------------------------------------------------
 * 安全设计(防纯前端破解):
 *  1. 题目与答案在服务端生成并存入 Session,前端只收到形状渲染数据(无答案、无题解);
 *  2. POST ?action=verify 由服务端判定点选结果:有效期 120s、人类反应下限 800ms、限 3 次;
 *  3. 通过后签发一次性 token(5 分钟有效),POST ?action=login 服务端校验并立即销毁;
 *  4. 换题接口限流(60s 内 ≤ 20 次),防暴力枚举。
 * 路由:
 *  GET  /captcha.php                 页面
 *  GET  /captcha.php?action=challenge 下发新题
 *  POST /captcha.php?action=verify    提交点选 id(FormData: id)
 *  POST /captcha.php?action=login     登录(FormData: account, password, token)
 */
if (session_status() !== PHP_SESSION_ACTIVE) { session_start(); }
header('X-Content-Type-Options: nosniff');
header('Cache-Control: no-store');

define('SG_W', 600);
define('SG_H', 280);
define('SG_SHAPES', 6);
define('SG_LIFE', 120);        // 题目有效期(秒)
define('SG_ATTEMPTS', 3);      // 每题容错次数
define('SG_MIN_MS', 800);      // 人类反应下限(毫秒),低于视为机器
define('SG_TOKEN_LIFE', 300);  // token 有效期(秒)

/* ================= 服务端:出题 / 判题 / 校验 ================= */

function sg_types() {
    return array('sphere' => '球体', 'cylinder' => '圆柱体', 'cube' => '正方体', 'cuboid' => '长方体', 'cone' => '圆锥体');
}
function sg_colors() {
    return array(
        array('name' => '红色', 'h' => 4,   's' => 74, 'l' => 50),
        array('name' => '蓝色', 'h' => 217, 's' => 84, 'l' => 48),
        array('name' => '绿色', 'h' => 130, 's' => 64, 'l' => 42),
        array('name' => '橙色', 'h' => 27,  's' => 92, 'l' => 52),
        array('name' => '青色', 'h' => 190, 's' => 72, 'l' => 40),
    );
}
function sg_randf($a, $b) { return $a + mt_rand() / mt_getrandmax() * ($b - $a); }
function sg_dims($type, $s) {
    switch ($type) {
        case 'sphere':   return array('r' => 30 * $s);
        case 'cylinder': return array('w' => 46 * $s, 'h' => 58 * $s, 'ry' => 9 * $s);
        case 'cube':     return array('w' => 40 * $s, 'd' => 40 * $s, 'h' => 40 * $s);
        case 'cuboid':   return array('w' => 34 * $s, 'd' => 26 * $s, 'h' => 58 * $s);
        default:         return array('rx' => 26 * $s, 'h' => 60 * $s, 'ry' => 9 * $s);
    }
}
function sg_footprint($type, $d) {
    if ($type === 'sphere')   return $d['r'] * 1.25;
    if ($type === 'cylinder') return $d['w'] * 0.85;
    if ($type === 'cone')     return $d['rx'] * 1.25;
    return ($d['w'] + $d['d']) * 0.62;
}
function sg_rate_ok() {
    $now = time();
    $log = isset($_SESSION['sg_rl']) ? $_SESSION['sg_rl'] : array();
    $keep = array();
    foreach ($log as $t) { if ($t > $now - 60) $keep[] = $t; }
    $keep[] = $now;
    $_SESSION['sg_rl'] = $keep;
    return count($keep) <= 20;
}
function sg_purge_tokens() {
    if (empty($_SESSION['sg_tokens'])) return;
    $now = time();
    foreach ($_SESSION['sg_tokens'] as $tok => $exp) { if ($exp <= $now) unset($_SESSION['sg_tokens'][$tok]); }
}

function sg_generate_challenge() {
    $types = sg_types(); $colors = sg_colors();
    $typeKeys = array_keys($types);
    $color = $colors[array_rand($colors)];
    $type  = $typeKeys[array_rand($typeKeys)];
    $extremum = mt_rand(0, 1) ? 'max' : 'min';
    $sizes = mt_rand(0, 1) ? array(0.72, 1.2) : array(0.68, 1.0, 1.32);

    $shapes = a.........完整代码请登录后点击上方下载按钮下载查看

网友评论0