From b1ec15a5219eba285b82265d4037d681ce9cc921 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A6=99=E7=A0=81=E7=94=9F=E8=8A=B1?= <18523774412@qq.com> Date: Fri, 27 Sep 2024 20:38:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=A2=9E=E5=8A=A0=E5=89=8D=E5=8F=B0?= =?UTF-8?q?=E4=BC=9A=E5=91=98=E7=99=BB=E5=BD=95=E9=AA=8C=E8=AF=81=E7=A0=81?= =?UTF-8?q?=E5=BC=80=E5=85=B3=E9=85=8D=E7=BD=AE=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/controller/User.php | 11 ++++++++--- app/api/validate/User.php | 23 +++++++++++++++++++++-- config/buildadmin.php | 2 ++ web/src/views/frontend/user/login.vue | 5 ++++- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/app/api/controller/User.php b/app/api/controller/User.php index 117b08a5..8ebdfeac 100644 --- a/app/api/controller/User.php +++ b/app/api/controller/User.php @@ -39,6 +39,8 @@ class User extends Frontend ], $this->auth::LOGIN_RESPONSE_CODE); } + $userLoginCaptchaSwitch = Config::get('buildadmin.user_login_captcha'); + if ($this->request->isPost()) { $params = $this->request->post(['tab', 'email', 'mobile', 'username', 'password', 'keep', 'captcha', 'captchaId', 'captchaInfo', 'registerType']); if (!in_array($params['tab'], ['login', 'register'])) { @@ -53,9 +55,11 @@ class User extends Frontend } if ($params['tab'] == 'login') { - $captchaObj = new ClickCaptcha(); - if (!$captchaObj->check($params['captchaId'], $params['captchaInfo'])) { - $this->error(__('Captcha error')); + if ($userLoginCaptchaSwitch) { + $captchaObj = new ClickCaptcha(); + if (!$captchaObj->check($params['captchaId'], $params['captchaInfo'])) { + $this->error(__('Captcha error')); + } } $res = $this->auth->login($params['username'], $params['password'], (bool)$params['keep']); } elseif ($params['tab'] == 'register') { @@ -79,6 +83,7 @@ class User extends Frontend } $this->success('', [ + 'userLoginCaptchaSwitch' => $userLoginCaptchaSwitch, 'accountVerificationType' => get_account_verification_type() ]); } diff --git a/app/api/validate/User.php b/app/api/validate/User.php index 4cac86cb..9dc310b3 100644 --- a/app/api/validate/User.php +++ b/app/api/validate/User.php @@ -3,6 +3,7 @@ namespace app\api\validate; use think\Validate; +use think\facade\Config; class User extends Validate { @@ -13,7 +14,9 @@ class User extends Validate 'email' => 'email|unique:user', 'mobile' => 'mobile|unique:user', 'password' => 'require|regex:^(?!.*[&<>"\'\n\r]).{6,32}$', + // 注册邮箱或手机验证码 'captcha' => 'require', + // 登录点选验证码 'captchaId' => 'require', 'captchaInfo' => 'require', ]; @@ -22,10 +25,26 @@ class User extends Validate * 验证场景 */ protected $scene = [ - 'login' => ['password', 'captchaId', 'captchaInfo'], - 'register' => ['email', 'username', 'password', 'mobile', 'captcha'], + 'register' => ['username', 'password', 'email', 'mobile', 'captcha'], ]; + /** + * 登录验证场景 + */ + public function sceneLogin(): User + { + $fields = ['username', 'password']; + + // 根据系统配置的登录验证码开关调整验证场景的字段 + $userLoginCaptchaSwitch = Config::get('buildadmin.user_login_captcha'); + if ($userLoginCaptchaSwitch) { + $fields[] = 'captchaId'; + $fields[] = 'captchaInfo'; + } + + return $this->only($fields)->remove('username', ['regex', 'unique']); + } + public function __construct() { $this->field = [ diff --git a/config/buildadmin.php b/config/buildadmin.php index 099f2a7d..12795473 100644 --- a/config/buildadmin.php +++ b/config/buildadmin.php @@ -6,6 +6,8 @@ return [ // 允许跨域访问的域名 'cors_request_domain' => 'localhost,127.0.0.1', + // 是否开启会员登录验证码 + 'user_login_captcha' => true, // 是否开启管理员登录验证码 'admin_login_captcha' => true, // 会员登录失败可重试次数,false则无限 diff --git a/web/src/views/frontend/user/login.vue b/web/src/views/frontend/user/login.vue index dfae3fb7..56bf803f 100644 --- a/web/src/views/frontend/user/login.vue +++ b/web/src/views/frontend/user/login.vue @@ -316,6 +316,7 @@ interface State { password: string } dialogWidth: number + userLoginCaptchaSwitch: boolean accountVerificationType: string[] codeSendCountdown: number submitRetrieveLoading: boolean @@ -345,6 +346,7 @@ const state: State = reactive({ password: '', }, dialogWidth: 36, + userLoginCaptchaSwitch: true, accountVerificationType: [], codeSendCountdown: 0, submitRetrieveLoading: false, @@ -398,7 +400,7 @@ const resize = () => { const onSubmitPre = () => { formRef.value?.validate((valid) => { if (!valid) return - if (state.form.tab == 'login') { + if (state.form.tab == 'login' && state.userLoginCaptchaSwitch) { clickCaptcha(state.form.captchaId, (captchaInfo: string) => onSubmit(captchaInfo)) } else { onSubmit() @@ -510,6 +512,7 @@ onMounted(async () => { useEventListener(window, 'resize', resize) checkIn('get').then((res) => { + state.userLoginCaptchaSwitch = res.data.userLoginCaptchaSwitch state.accountVerificationType = res.data.accountVerificationType state.retrievePasswordForm.type = res.data.accountVerificationType.length > 0 ? res.data.accountVerificationType[0] : '' })