feat 增加图形验证码
This commit is contained in:
@@ -23,12 +23,23 @@ namespace app\admin\controller;
|
||||
|
||||
use app\admin\logic\LoginLogic;
|
||||
use app\admin\validate\Login;
|
||||
use app\common\server\CaptchaService;
|
||||
use Exception;
|
||||
use think\facade\Url;
|
||||
|
||||
class Account extends AdminBase
|
||||
{
|
||||
|
||||
public $like_not_need_login = ['login'];
|
||||
public $like_not_need_login = ['login', 'captcha'];
|
||||
|
||||
/**
|
||||
* @notes 图形验证码
|
||||
* @throws Exception
|
||||
*/
|
||||
public function captcha()
|
||||
{
|
||||
$this->_success('OK', CaptchaService::create());
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录
|
||||
@@ -61,4 +72,4 @@ class Account extends AdminBase
|
||||
$url = Url::build('account/login');
|
||||
$this->redirect($url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
namespace app\admin\validate;
|
||||
|
||||
use app\common\server\CaptchaService;
|
||||
use think\Db;
|
||||
use think\facade\Cache;
|
||||
use think\Validate;
|
||||
@@ -27,15 +28,38 @@ class Login extends Validate
|
||||
{
|
||||
protected $rule = [
|
||||
'account' => 'require',
|
||||
'captcha_key' => 'require',
|
||||
'captcha' => 'require|checkCaptcha',
|
||||
'password' => 'require|password',
|
||||
];
|
||||
|
||||
protected $message = [
|
||||
'account.require' => '账号不能为空',
|
||||
'captcha_key.require' => '图形验证码已失效,请重新获取',
|
||||
'captcha.require' => '请输入图形验证码',
|
||||
'password.require' => '密码不能为空',
|
||||
'password.password' => '账号密码错误',
|
||||
];
|
||||
|
||||
/**
|
||||
* @notes 校验图形验证码
|
||||
* @param $captcha
|
||||
* @param $rule
|
||||
* @param $data
|
||||
* @return string|true
|
||||
*/
|
||||
public function checkCaptcha($captcha, $rule, $data)
|
||||
{
|
||||
unset($rule);
|
||||
$key = trim($data['captcha_key'] ?? '');
|
||||
|
||||
if (CaptchaService::verify($key, (string) $captcha)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return '图形验证码错误';
|
||||
}
|
||||
|
||||
/**
|
||||
* 账号密码验证码
|
||||
* @param $password
|
||||
@@ -90,4 +114,4 @@ class Login extends Validate
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,12 +21,23 @@
|
||||
namespace app\api\controller;
|
||||
use app\api\logic\LoginLogic;
|
||||
use app\api\validate\WechatLoginValidate;
|
||||
use app\common\server\CaptchaService;
|
||||
use app\common\server\ConfigServer;
|
||||
use Exception;
|
||||
|
||||
class Account extends ApiBase
|
||||
{
|
||||
|
||||
public $like_not_need_login = ['register','applogin', 'login', 'mnplogin', 'codeurl', 'oalogin', 'oplogin','logout','smslogin', 'uinAppLogin', 'silentLogin', 'authLogin'];
|
||||
public $like_not_need_login = ['captcha', 'register','applogin', 'login', 'mnplogin', 'codeurl', 'oalogin', 'oplogin','logout','smslogin', 'uinAppLogin', 'silentLogin', 'authLogin'];
|
||||
|
||||
/**
|
||||
* @notes 图形验证码
|
||||
* @throws Exception
|
||||
*/
|
||||
public function captcha()
|
||||
{
|
||||
$this->_success('OK', CaptchaService::create());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -323,4 +334,4 @@ class Account extends ApiBase
|
||||
|
||||
$this->_success('绑定成功');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ use think\Db;
|
||||
use think\facade\Cache;
|
||||
use think\Validate;
|
||||
use app\common\logic\SmsLogic;
|
||||
use app\common\server\CaptchaService;
|
||||
class Login extends Validate
|
||||
{
|
||||
|
||||
@@ -39,6 +40,8 @@ class Login extends Validate
|
||||
|
||||
protected $rule = [
|
||||
'account' => 'require',
|
||||
'captcha_key' => 'require',
|
||||
'captcha' => 'require|checkCaptcha',
|
||||
'password' => 'require|password',
|
||||
'client' => 'require|in:'. Client_::mnp . ',' . Client_::oa . ',' . Client_::ios . ',' . Client_::android. ',' .Client_::pc. ','. Client_::h5,
|
||||
'code'=>'require|checkCode',
|
||||
@@ -46,6 +49,8 @@ class Login extends Validate
|
||||
|
||||
protected $message = [
|
||||
'account.require' => '请输入账号或手机号',
|
||||
'captcha_key.require' => '图形验证码已失效,请重新获取',
|
||||
'captcha.require' => '请输入图形验证码',
|
||||
'password.require' => '请输入密码',
|
||||
'password.password' => '密码错误',
|
||||
'client.in' => '当前只支持h5和app登录',
|
||||
@@ -62,6 +67,25 @@ class Login extends Validate
|
||||
$this->only(['account','code','client']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 校验图形验证码
|
||||
* @param $captcha
|
||||
* @param $rule
|
||||
* @param $data
|
||||
* @return string|true
|
||||
*/
|
||||
public function checkCaptcha($captcha, $rule, $data)
|
||||
{
|
||||
unset($rule);
|
||||
$key = trim($data['captcha_key'] ?? '');
|
||||
|
||||
if (CaptchaService::verify($key, (string) $captcha)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return '图形验证码错误';
|
||||
}
|
||||
|
||||
|
||||
public static function checkCode($value,$rule,$data){
|
||||
$sms_logic = new SmsLogic($data['message_key'],$data['account'],$value);
|
||||
@@ -145,4 +169,4 @@ class Login extends Validate
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
141
server/application/common/server/CaptchaService.php
Normal file
141
server/application/common/server/CaptchaService.php
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\server;
|
||||
|
||||
use Exception;
|
||||
use think\facade\Cache;
|
||||
|
||||
class CaptchaService
|
||||
{
|
||||
const CHARS = '0123456789';
|
||||
const LENGTH = 4;
|
||||
const EXPIRE_SECONDS = 60;
|
||||
const CACHE_PREFIX = 'captcha:';
|
||||
|
||||
/**
|
||||
* @notes 创建图形验证码
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function create()
|
||||
{
|
||||
$code = self::createCode();
|
||||
$key = md5(uniqid((string) random_int(100000, 999999), true));
|
||||
|
||||
Cache::set(self::CACHE_PREFIX . $key, $code, self::EXPIRE_SECONDS);
|
||||
|
||||
return [
|
||||
'key' => $key,
|
||||
'image' => 'data:image/png;base64,' . base64_encode(self::drawImage($code)),
|
||||
'expire' => self::EXPIRE_SECONDS,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 校验图形验证码,一次性消费
|
||||
* @param string $key
|
||||
* @param string $code
|
||||
* @return bool
|
||||
*/
|
||||
public static function verify($key, $code)
|
||||
{
|
||||
$cacheKey = self::CACHE_PREFIX . trim((string) $key);
|
||||
$captcha = Cache::get($cacheKey);
|
||||
Cache::rm($cacheKey);
|
||||
|
||||
if (empty($captcha)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return hash_equals($captcha, strtolower(trim((string) $code)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 创建验证码字符
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function createCode()
|
||||
{
|
||||
$code = '';
|
||||
$maxIndex = strlen(self::CHARS) - 1;
|
||||
|
||||
for ($i = 0; $i < self::LENGTH; $i++) {
|
||||
$code .= self::CHARS[random_int(0, $maxIndex)];
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 绘制验证码图片
|
||||
* @param string $code
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function drawImage($code)
|
||||
{
|
||||
$width = 120;
|
||||
$height = 42;
|
||||
$image = imagecreatetruecolor($width, $height);
|
||||
$backgroundColor = imagecolorallocate($image, 245, 247, 250);
|
||||
imagefilledrectangle($image, 0, 0, $width, $height, $backgroundColor);
|
||||
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$lineColor = imagecolorallocate(
|
||||
$image,
|
||||
random_int(90, 180),
|
||||
random_int(90, 180),
|
||||
random_int(90, 180)
|
||||
);
|
||||
|
||||
imageline(
|
||||
$image,
|
||||
random_int(0, $width),
|
||||
random_int(0, $height),
|
||||
random_int(0, $width),
|
||||
random_int(0, $height),
|
||||
$lineColor
|
||||
);
|
||||
}
|
||||
|
||||
for ($i = 0; $i < 120; $i++) {
|
||||
$pixelColor = imagecolorallocate(
|
||||
$image,
|
||||
random_int(120, 220),
|
||||
random_int(120, 220),
|
||||
random_int(120, 220)
|
||||
);
|
||||
imagesetpixel(
|
||||
$image,
|
||||
random_int(0, $width - 1),
|
||||
random_int(0, $height - 1),
|
||||
$pixelColor
|
||||
);
|
||||
}
|
||||
|
||||
for ($i = 0; $i < self::LENGTH; $i++) {
|
||||
$textColor = imagecolorallocate(
|
||||
$image,
|
||||
random_int(20, 90),
|
||||
random_int(20, 90),
|
||||
random_int(20, 90)
|
||||
);
|
||||
imagestring(
|
||||
$image,
|
||||
5,
|
||||
18 + $i * 23,
|
||||
random_int(10, 18),
|
||||
$code[$i],
|
||||
$textColor
|
||||
);
|
||||
}
|
||||
|
||||
ob_start();
|
||||
imagepng($image);
|
||||
$content = ob_get_clean();
|
||||
imagedestroy($image);
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user