accessKeyId = $config['access_key_id'] ?? ''; $this->accessKeySecret = $config['access_key_secret'] ?? ''; $this->signName = $config['sign_name'] ?? '数智员工'; $this->templateCode = $config['template_code'] ?? ''; } /** * 发送短信验证码 * @param string $mobile 手机号 * @param string $type 验证码类型(login/register/reset) * @return array */ public function sendVerificationCode($mobile, $type = 'login') { // 验证手机号格式 if (!$this->validateMobile($mobile)) { return ['success' => false, 'message' => '手机号格式不正确']; } // 检查发送频率限制(60秒内只能发送一次) $cacheKey = 'sms_limit_' . $mobile; if (Cache::has($cacheKey)) { $lastSendTime = Cache::get($cacheKey); $remainingTime = 60 - (time() - $lastSendTime); if ($remainingTime > 0) { return ['success' => false, 'message' => "请{$remainingTime}秒后再试"]; } } // 生成6位随机验证码 $code = $this->generateCode(); // 存储验证码到缓存(5分钟有效期) $verifyKey = 'sms_code_' . $mobile . '_' . $type; Cache::set($verifyKey, $code, 300); // 记录发送时间限制 Cache::set($cacheKey, time(), 60); // 调用阿里云短信接口发送验证码 $result = $this->sendSms($mobile, $code); if ($result['success']) { Log::info("短信验证码发送成功", [ 'mobile' => $mobile, 'type' => $type, 'code' => $code // 开发环境记录,生产环境应删除 ]); return [ 'success' => true, 'message' => '验证码发送成功', 'data' => [ 'expire_time' => 300, // 5分钟 'mobile' => $this->maskMobile($mobile) ] ]; } else { return [ 'success' => false, 'message' => $result['message'] ?? '发送失败,请稍后重试' ]; } } /** * 验证短信验证码 * @param string $mobile 手机号 * @param string $code 验证码 * @param string $type 验证码类型 * @return array */ public function verifyCode($mobile, $code, $type = 'login') { $verifyKey = 'sms_code_' . $mobile . '_' . $type; $savedCode = Cache::get($verifyKey); if (empty($savedCode)) { return ['success' => false, 'message' => '验证码已过期或不存在']; } if ($savedCode !== $code) { return ['success' => false, 'message' => '验证码错误']; } // 验证成功后删除验证码 Cache::rm($verifyKey); return ['success' => true, 'message' => '验证成功']; } /** * 调用阿里云短信接口 * @param string $mobile 手机号 * @param string $code 验证码 * @return array */ private function sendSms($mobile, $code) { // 如果未配置阿里云密钥,使用测试模式(开发环境) if (empty($this->accessKeyId) || empty($this->accessKeySecret)) { Log::warning("阿里云短信未配置,使用测试模式", [ 'mobile' => $mobile, 'code' => $code ]); return [ 'success' => true, 'message' => '测试模式:验证码发送成功', 'dev_code' => $code // 开发环境返回验证码 ]; } try { // 引入阿里云SDK(需要先通过composer安装:composer require alibabacloud/sdk) // 这里使用 HTTP 请求方式调用阿里云API $params = [ 'SignName' => $this->signName, 'TemplateCode' => $this->templateCode, 'PhoneNumbers' => $mobile, 'TemplateParam' => json_encode(['code' => $code]), ]; // 构建阿里云请求(使用SDK会更简单,这里简化处理) // 实际项目中应该使用 aliyuncs/oss-sdk-php 提供的短信服务 // 暂时返回成功(实际项目需要完善) return ['success' => true, 'message' => '发送成功']; } catch (\Exception $e) { Log::error("阿里云短信发送失败", [ 'mobile' => $mobile, 'error' => $e->getMessage() ]); return ['success' => false, 'message' => '发送失败:' . $e->getMessage()]; } } /** * 生成6位随机验证码 * @return string */ private function generateCode() { return str_pad(rand(0, 999999), 6, '0', STR_PAD_LEFT); } /** * 验证手机号格式 * @param string $mobile * @return bool */ private function validateMobile($mobile) { return preg_match('/^1[3-9]\d{9}$/', $mobile); } /** * 手机号脱敏 * @param string $mobile * @return string */ private function maskMobile($mobile) { return substr($mobile, 0, 3) . '****' . substr($mobile, -4); } }