生成图形验证码
parent
e12d060bd2
commit
9521551704
|
|
@ -0,0 +1,73 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api\V1;
|
||||||
|
|
||||||
|
use App\Services\CaptchaService;
|
||||||
|
use Gregwar\Captcha\CaptchaBuilder;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class CaptchaController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 创建图形验证码
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param \App\Services\CaptchaService $captchaService
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function store(Request $request, CaptchaService $captchaService)
|
||||||
|
{
|
||||||
|
$key = $request->filled('key') ? $request->input('key') : Str::random(16);
|
||||||
|
|
||||||
|
$builder = $this->builder();
|
||||||
|
$builder->build(
|
||||||
|
(int) $request->input('w', 150),
|
||||||
|
(int) $request->input('h', 40),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (strlen($key) <= 32) {
|
||||||
|
$captchaService->put($key, $builder->getPhrase());
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'key' => $key,
|
||||||
|
'img' => $builder->inline(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看图形验证码
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param \App\Services\CaptchaService $captchaService
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function show($key, Request $request, CaptchaService $captchaService)
|
||||||
|
{
|
||||||
|
$builder = $this->builder();
|
||||||
|
$builder->build(
|
||||||
|
(int) $request->query('w', 150),
|
||||||
|
(int) $request->query('h', 40),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (strlen($key) <= 32) {
|
||||||
|
$captchaService->put($key, $builder->getPhrase());
|
||||||
|
}
|
||||||
|
|
||||||
|
return response($builder->get())
|
||||||
|
->header('Content-Type', 'image/jpeg')
|
||||||
|
->header('Cache-Control', 'no-cache');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图形验证码生成器
|
||||||
|
*
|
||||||
|
* @return \Gregwar\Captcha\CaptchaBuilder
|
||||||
|
*/
|
||||||
|
protected function builder(): CaptchaBuilder
|
||||||
|
{
|
||||||
|
return new CaptchaBuilder(Str::random(5));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
|
||||||
|
use App\Exceptions\BizException;
|
||||||
|
use Illuminate\Contracts\Cache\Repository as Cache;
|
||||||
|
|
||||||
|
class CaptchaService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $cachePrefix = 'captchas_';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Illuminate\Contracts\Cache\Repository $cache
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
protected Cache $cache,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将验证码存入缓存中
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param string $phrase
|
||||||
|
* @param integer $ttl
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function put(string $key, string $phrase, int $ttl = 300): void
|
||||||
|
{
|
||||||
|
$this->cache->put($this->cacheKey($key), $phrase, $ttl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验验证码是否正确
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param string $phrase
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function testPhrase(string $key, string $phrase): bool
|
||||||
|
{
|
||||||
|
if ($phrase === '') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$value = (string) $this->cache->pull(
|
||||||
|
$this->cacheKey($key)
|
||||||
|
);
|
||||||
|
|
||||||
|
return strtolower($value) === strtolower($phrase);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验验证码是否正确
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param string $phrase
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @throws \App\Exceptions\BizException
|
||||||
|
*/
|
||||||
|
public function validatePhrase(string $key, string $phrase): void
|
||||||
|
{
|
||||||
|
if (! $this->testPhrase($key, $phrase)) {
|
||||||
|
throw new BizException(__('Invalid captcha'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成验证码缓存的 key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function cacheKey(string $key): string
|
||||||
|
{
|
||||||
|
return $this->cachePrefix.$key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
"php": "^8.0",
|
"php": "^8.0",
|
||||||
"dcat/laravel-admin": "2.1.5-beta",
|
"dcat/laravel-admin": "2.1.5-beta",
|
||||||
"fruitcake/laravel-cors": "^2.0",
|
"fruitcake/laravel-cors": "^2.0",
|
||||||
|
"gregwar/captcha": "^1.1",
|
||||||
"guzzlehttp/guzzle": "^7.0.1",
|
"guzzlehttp/guzzle": "^7.0.1",
|
||||||
"kalnoy/nestedset": "^6.0",
|
"kalnoy/nestedset": "^6.0",
|
||||||
"laravel/framework": "^8.65",
|
"laravel/framework": "^8.65",
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "50de900b3113c2d3d3f9c191fd6e6693",
|
"content-hash": "865b93f26360dff74bb3e2c2c6dac800",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "asm89/stack-cors",
|
"name": "asm89/stack-cors",
|
||||||
|
|
@ -1133,6 +1133,69 @@
|
||||||
],
|
],
|
||||||
"time": "2021-10-17T19:48:54+00:00"
|
"time": "2021-10-17T19:48:54+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "gregwar/captcha",
|
||||||
|
"version": "v1.1.9",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/Gregwar/Captcha.git",
|
||||||
|
"reference": "4bb668e6b40e3205a020ca5ee4ca8cff8b8780c5"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/Gregwar/Captcha/zipball/4bb668e6b40e3205a020ca5ee4ca8cff8b8780c5",
|
||||||
|
"reference": "4bb668e6b40e3205a020ca5ee4ca8cff8b8780c5",
|
||||||
|
"shasum": "",
|
||||||
|
"mirrors": [
|
||||||
|
{
|
||||||
|
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||||
|
"preferred": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-gd": "*",
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"php": ">=5.3.0",
|
||||||
|
"symfony/finder": "*"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^6.4"
|
||||||
|
},
|
||||||
|
"type": "captcha",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Gregwar\\": "src/Gregwar"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Grégoire Passault",
|
||||||
|
"email": "g.passault@gmail.com",
|
||||||
|
"homepage": "http://www.gregwar.com/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jeremy Livingston",
|
||||||
|
"email": "jeremy.j.livingston@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Captcha generator",
|
||||||
|
"homepage": "https://github.com/Gregwar/Captcha",
|
||||||
|
"keywords": [
|
||||||
|
"bot",
|
||||||
|
"captcha",
|
||||||
|
"spam"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/Gregwar/Captcha/issues",
|
||||||
|
"source": "https://github.com/Gregwar/Captcha/tree/master"
|
||||||
|
},
|
||||||
|
"time": "2020-03-24T14:39:05+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "guzzlehttp/guzzle",
|
"name": "guzzlehttp/guzzle",
|
||||||
"version": "7.4.0",
|
"version": "7.4.0",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
":resource not found": ":resource 未找到",
|
":resource not found": ":resource 未找到",
|
||||||
|
"Invalid captcha": "无效的验证码",
|
||||||
"Invalid invitation code": "无效的邀请码",
|
"Invalid invitation code": "无效的邀请码",
|
||||||
"Registration failed, please try again": "注册失败,请重试"
|
"Registration failed, please try again": "注册失败,请重试"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Http\Controllers\Api\V1\CaptchaController;
|
||||||
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
|
Route::post('captchas', [CaptchaController::class, 'store']);
|
||||||
|
Route::get('captchas/{captcha}', [CaptchaController::class, 'show']);
|
||||||
Loading…
Reference in New Issue