图形验证码
parent
f0dc08c21c
commit
522d2f8128
|
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\AdminPermission;
|
use App\Models\AdminPermission;
|
||||||
use App\Models\AdminUser;
|
use App\Models\AdminUser;
|
||||||
|
use App\Services\CaptchaService;
|
||||||
use Illuminate\Contracts\Cache\Repository as Cache;
|
use Illuminate\Contracts\Cache\Repository as Cache;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
|
@ -15,13 +16,19 @@ class AuthController extends Controller
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function login(Request $request)
|
public function login(Request $request, CaptchaService $captchaService)
|
||||||
{
|
{
|
||||||
$request->validate([
|
$request->validate([
|
||||||
'username' => 'required',
|
'username' => 'required',
|
||||||
'password' => 'required',
|
'password' => 'required',
|
||||||
|
'captcha_key' => 'required',
|
||||||
|
'captcha_value' => 'required',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
if (! $captchaService->testPhrase($request->input('captcha_key'), $request->input('captcha_value'))) {
|
||||||
|
return $this->error('验证码错误');
|
||||||
|
}
|
||||||
|
|
||||||
$username = $request->input('username');
|
$username = $request->input('username');
|
||||||
|
|
||||||
$user = AdminUser::where(['username' => $username])->first();
|
$user = AdminUser::where(['username' => $username])->first();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Services\CaptchaService;
|
||||||
|
use Gregwar\Captcha\CaptchaBuilder;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class CaptchaController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 创建图形验证码
|
||||||
|
*/
|
||||||
|
public function store(Request $request, CaptchaService $captchaService)
|
||||||
|
{
|
||||||
|
$request->validate([
|
||||||
|
'key' => ['bail', 'filled', 'string', 'max:32'],
|
||||||
|
'w' => ['bail', 'int'],
|
||||||
|
'h' => ['bail', 'int'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$builder = $this->builder();
|
||||||
|
$builder->build($request->input('w', 150), $request->input('h', 40));
|
||||||
|
|
||||||
|
$captchaService->put(
|
||||||
|
$key = $request->input('key', Str::random(16)),
|
||||||
|
$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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -17,6 +17,9 @@ use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
Route::post('auth/login', [AuthController::class, 'login']);
|
Route::post('auth/login', [AuthController::class, 'login']);
|
||||||
|
|
||||||
|
Route::post('captchas', [CaptchaController::class, 'store']);
|
||||||
|
Route::get('captchas/{captcha}', [CaptchaController::class, 'show']);
|
||||||
|
|
||||||
Route::group([
|
Route::group([
|
||||||
'middleware' => ['auth:sanctum'],
|
'middleware' => ['auth:sanctum'],
|
||||||
], function () {
|
], function () {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue