'require|checkAccount', 'scene' => 'require|in:' . LoginEnum::ACCOUNT_PASSWORD . ',' . LoginEnum::MOBILE_CAPTCHA . '|checkScene', ]; protected $message = [ 'account.require' => '请输入账号', 'scene.require' => '场景不能为空', 'scene.in' => '场景值错误', ]; public function checkAccount($account): bool|string { $user = User::field('id,status')->where('phone',$account)->findOrEmpty(); if($user->isEmpty()){ return '账号错误'; } if ($user['status'] != 0) { return '用户已冻结或删除'; } return true; } public function checkScene($scene, $rule, $data): bool|string { // 判断scene的值 if (!in_array($scene, [LoginEnum::ACCOUNT_PASSWORD,LoginEnum::MOBILE_CAPTCHA])) { return '不支持的登录方式'; } if (LoginEnum::ACCOUNT_PASSWORD == $scene) { // 账号密码登录 if (empty($data['password'])) { return '请输入密码'; } return $this->checkPassword($data['password'], [], $data); }else{ // 手机验证码登录 if (empty($data['code'])) { return '请输入手机验证码'; } return $this->checkCode($data['code'], [], $data); } } protected function checkPassword($password, $other, $data): bool|string { //账号安全机制,连续输错后锁定,防止账号密码暴力破解 $userAccountSafeCache = new UserAccountSafeCache(); if (!$userAccountSafeCache->isSafe()) { return '密码连续' . $userAccountSafeCache->count . '次输入错误,请' . $userAccountSafeCache->minute . '分钟后重试'; } $userInfo = User::field('password')->where('phone',$data['account'])->findOrEmpty(); $passwordSalt = Config::get('project.unique_identification'); if ($userInfo['password'] !== create_password($password, $passwordSalt)) { $userAccountSafeCache->record(); return '密码错误'; } $userAccountSafeCache->relieve(); return true; } public function checkCode($code, $rule, $data): bool|string { $smsDriver = new SmsDriver(); $result = $smsDriver->verify($data['account'], $code, NoticeEnum::LOGIN_CAPTCHA); if ($result) { return true; } return '验证码错误'; } }