SpringBoot项目实战:5分钟搞定阿里云短信验证码(附防刷Redis配置)

发布时间:2026/6/9 1:34:43

SpringBoot项目实战:5分钟搞定阿里云短信验证码(附防刷Redis配置) SpringBoot实战阿里云短信验证码集成与Redis防刷策略短信验证码作为现代应用的身份验证基石其稳定性和安全性直接影响用户体验和系统可靠性。对于Java开发者而言如何在SpringBoot项目中快速集成阿里云短信服务同时规避恶意刷取风险是每个上线项目必须跨越的技术门槛。1. 阿里云短信服务基础配置在开始编码前我们需要完成阿里云侧的准备工作。登录阿里云控制台进入「短信服务」模块这里需要重点关注三个核心配置项签名申请选择签名类型为「验证码」填写签名来源如企业官网或APP名称上传对应的资质证明文件模板创建新建「验证码」类型模板内容示例您的验证码为${code}5分钟内有效权限配置为操作账号开通AliyunDysmsFullAccess权限策略注意正式环境签名审核通常需要1-2个工作日建议在项目初期就提前准备关键参数获取位置参数类型获取路径示例AccessKey控制台 访问控制 用户管理LTAI5txxxxxxxxxx签名名称短信服务 签名管理阿里云验证模板CODE短信服务 模板管理SMS_1549509092. SpringBoot工程初始化创建标准的SpringBoot项目后首先配置必要的依赖项。除了基础的web starter还需要添加!-- 阿里云SDK核心库 -- dependency groupIdcom.aliyun/groupId artifactIdaliyun-java-sdk-core/artifactId version4.5.16/version /dependency !-- 短信服务专用SDK -- dependency groupIdcom.aliyun/groupId artifactIddysmsapi20170525/artifactId version2.0.23/version /dependency !-- Redis集成 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId /dependency在application.yml中配置关键参数aliyun: sms: access-key-id: ${ALIYUN_ACCESS_KEY} access-key-secret: ${ALIYUN_ACCESS_SECRET} sign-name: 阿里云验证 template-code: SMS_154950909 endpoint: dysmsapi.aliyuncs.com spring: redis: host: localhost port: 6379 timeout: 30003. 验证码服务层实现验证码生成建议采用线程安全的ThreadLocalRandom替代传统Random类public class VerificationCodeUtil { private static final String NUMBERS 0123456789; public static String generate(int length) { StringBuilder sb new StringBuilder(length); for (int i 0; i length; i) { int index ThreadLocalRandom.current().nextInt(NUMBERS.length()); sb.append(NUMBERS.charAt(index)); } return sb.toString(); } }短信发送服务实现要点Service RequiredArgsConstructor public class SmsService { private final AliyunSmsConfig smsConfig; public SendSmsResponse sendVerificationCode(String phone, String code) throws Exception { Config config new Config() .setAccessKeyId(smsConfig.getAccessKeyId()) .setAccessKeySecret(smsConfig.getAccessKeySecret()); config.endpoint smsConfig.getEndpoint(); Client client new Client(config); SendSmsRequest request new SendSmsRequest() .setPhoneNumbers(phone) .setSignName(smsConfig.getSignName()) .setTemplateCode(smsConfig.getTemplateCode()) .setTemplateParam({\code\:\ code \}); return client.sendSms(request); } }4. Redis防刷策略深度优化基础防刷方案存在三个潜在漏洞未限制单位时间发送次数未校验验证码有效性缺乏IP维度限制改进后的Redis存储结构设计// 验证码存储Key设计 String codeKey sms:code: phone; // 发送次数计数Key设计 String countKey sms:count: phone; // IP限制Key设计 String ipKey sms:ip: ipAddress; // 复合校验逻辑 public boolean allowSend(String phone, String ip) { // 单IP每日限制 Long ipCount redisTemplate.opsForValue().increment(ipKey); if (ipCount 1) { redisTemplate.expire(ipKey, 1, TimeUnit.DAYS); } if (ipCount 50) { return false; } // 手机号频次控制 Long phoneCount redisTemplate.opsForValue().increment(countKey); if (phoneCount 1) { redisTemplate.expire(countKey, 1, TimeUnit.HOURS); } return phoneCount 5; }验证码校验服务示例public boolean verifyCode(String phone, String inputCode) { String storedCode redisTemplate.opsForValue().get(sms:code: phone); if (storedCode null || !storedCode.equals(inputCode)) { return false; } // 验证通过后立即删除缓存 redisTemplate.delete(sms:code: phone); return true; }5. 生产环境注意事项性能优化使用连接池配置RedisTemplate对短信发送接口实现异步处理添加熔断机制如Sentinel防止短信服务不可用安全增强// 图形验证码前置校验 GetMapping(/sms/code) public Result requestSmsCode( RequestParam String phone, RequestParam String captcha, HttpServletRequest request) { String sessionCaptcha (String) request.getSession() .getAttribute(captcha); if (!captcha.equalsIgnoreCase(sessionCaptcha)) { return Result.fail(图形验证码错误); } // ...后续短信发送逻辑 }监控建议通过阿里云云监控设置短信发送量告警记录Redis防刷触发日志用于安全审计定期统计各手机号验证码使用情况在用户注册流程中建议采用以下验证链前端图形验证码短信验证码频率控制最终验证码校验注册成功后的风控检查

相关新闻