feat: 注册验证码改为自动生成图形验证码
1. Common.php: 新增captcha()接口,生成算术验证码图片(base64) 2. Common.php: 新增checkCaptcha()静态方法,验证码校验+防重放 3. User.php: 注册接口移除邮箱/短信OTP验证,改用图形验证码 验证码5分钟过期,验证后立即销毁
This commit is contained in:
@@ -325,6 +325,93 @@ class Common extends Api
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册验证码图片 - 生成算术验证码并返回base64图片
|
||||
* GET /api/common/captcha
|
||||
*/
|
||||
public function captcha()
|
||||
{
|
||||
$a = mt_rand(1, 20);
|
||||
$b = mt_rand(1, 20);
|
||||
$operators = ['+', '-'];
|
||||
$op = $operators[array_rand($operators)];
|
||||
if ($op == '-' && $a < $b) {
|
||||
// 确保减法结果非负
|
||||
$tmp = $a; $a = $b; $b = $tmp;
|
||||
}
|
||||
$answer = ($op == '+') ? ($a + $b) : ($a - $b);
|
||||
$text = "{$a} {$op} {$b} = ?";
|
||||
|
||||
// 生成唯一key标识本次验证码
|
||||
$captcha_key = md5(uniqid(mt_rand(), true));
|
||||
|
||||
// 将答案存入缓存(使用ThinkPHP缓存,5分钟过期)
|
||||
cache('captcha_' . $captcha_key, strval($answer), 300);
|
||||
|
||||
// 生成验证码图片
|
||||
$width = 200;
|
||||
$height = 60;
|
||||
$img = imagecreatetruecolor($width, $height);
|
||||
|
||||
// 背景色
|
||||
$bgColor = imagecolorallocate($img, 240, 244, 250);
|
||||
imagefilledrectangle($img, 0, 0, $width, $height, $bgColor);
|
||||
|
||||
// 干扰线
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$lineColor = imagecolorallocate($img, mt_rand(100, 200), mt_rand(100, 200), mt_rand(100, 200));
|
||||
imageline($img, mt_rand(0, $width), mt_rand(0, $height), mt_rand(0, $width), mt_rand(0, $height), $lineColor);
|
||||
}
|
||||
|
||||
// 干扰点
|
||||
for ($i = 0; $i < 50; $i++) {
|
||||
$dotColor = imagecolorallocate($img, mt_rand(100, 255), mt_rand(100, 255), mt_rand(100, 255));
|
||||
imagesetpixel($img, mt_rand(0, $width), mt_rand(0, $height), $dotColor);
|
||||
}
|
||||
|
||||
// 文字颜色
|
||||
$textColor = imagecolorallocate($img, mt_rand(10, 80), mt_rand(10, 80), mt_rand(10, 80));
|
||||
|
||||
// 使用内置字体绘制文字
|
||||
$fontSize = 5; // imagestring内置字体最大5
|
||||
$textWidth = imagefontwidth($fontSize) * strlen($text);
|
||||
$textHeight = imagefontheight($fontSize);
|
||||
$x = ($width - $textWidth) / 2;
|
||||
$y = ($height - $textHeight) / 2;
|
||||
imagestring($img, $fontSize, $x, $y, $text, $textColor);
|
||||
|
||||
// 输出为base64
|
||||
ob_start();
|
||||
imagepng($img);
|
||||
$imgData = ob_get_clean();
|
||||
imagedestroy($img);
|
||||
|
||||
$base64 = 'data:image/png;base64,' . base64_encode($imgData);
|
||||
|
||||
$this->success('ok', [
|
||||
'captcha_key' => $captcha_key,
|
||||
'captcha_img' => $base64,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证注册验证码(内部调用)
|
||||
*/
|
||||
public static function checkCaptcha($captcha_key, $captcha_code)
|
||||
{
|
||||
if (empty($captcha_key) || empty($captcha_code)) {
|
||||
return false;
|
||||
}
|
||||
$answer = cache('captcha_' . $captcha_key);
|
||||
if ($answer === false || $answer === null) {
|
||||
return false;
|
||||
}
|
||||
$result = (trim($captcha_code) === trim($answer));
|
||||
// 验证后立即删除,防止重放
|
||||
cache('captcha_' . $captcha_key, null);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成随机key secrit
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user