SpringBoot 实现手机短信验证码
下面是我具体实现的
<!-- 阿里云OSS -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.8.3</version>
</dependency>
/**
* Created by mhSui on 2019/12/05.
*
* @author mhSui
*/
@Slf4j
@Configuration
public class SmsUtil {
@Value("${aliyun.accessKeyId}")
private String accessKeyId;
@Value("${aliyun.secret}")
private String secret;
@Value("${aliyun.signName}")
private String signName;
@Value("${aliyun.templateCode}")
private String templateCode;
@Value("${aliyun.paramName}")
private String paramName;
@Autowired
private RedisClient redisClient;
/**
* 发送短信.
* @param mobile 手机号
* @return String
*/
@SuppressWarnings("deprecated")
public String sendSms(String mobile) {
// 检验手机号码
boolean isPhone = isPhone(mobile);
if (!isPhone) {
return ProcessEnum.PHONE_FORMAT_ERROR;
}
// 校验是否重复发送
String code = this.redisClient.get(mobile);
if (code != null) {
return ProcessEnum.SMS_FREQUENTLY;
}
String kaptcha = this.getKaptcha();
Map<String, String> map = new HashMap<>(1);
map.put(this.paramName, kaptcha);
String templateParam = JSON.toJSONString(map);
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou",
this.accessKeyId, this.secret);
IAcsClient client = new DefaultAcsClient(profile);
CommonRequest request = new CommonRequest();
request.setMethod(MethodType.POST);
request.setDomain("dysmsapi.aliyuncs.com");
request.setVersion("2017-05-25");
request.setAction("SendSms");
request.putQueryParameter("RegionId", "cn-hangzhou");
request.putQueryParameter("PhoneNumbers", mobile);
request.putQueryParameter("SignName", this.signName);
request.putQueryParameter("TemplateCode", this.templateCode);
request.putQueryParameter("TemplateParam", templateParam);
try {
CommonResponse response = client.getCommonResponse(request);
String responseMessage = JSONObject.parseObject(response.getData())
.getString("Message");
if (!"ok".equals(responseMessage)) {
// 短信发送成功,将验证码存储到redis,并设置过期时间为5分钟
this.redisClient.set(mobile, kaptcha);
this.redisClient.expire(mobile, 15 * 60);
return ProcessEnum.SUCCESS;
}
}
catch (ClientException e) {
// 短信发送失败
return ProcessEnum.SMS_FAILED;
}
// 短信发送失败
return ProcessEnum.SMS_FAILED;
}
/**
* 中国电信号段 133、149、153、173、177、180、181、189、199. 中国联通号段
* 130、131、132、145、155、156、166、175、176、185、186. 中国移动号段
* 134(0-8)、135、136、137、138、139、147、150、151、152、157、158、159、178、182、183、184、187、188、198.
* 其他号段. 14号段以前为上网卡专属号段,如中国联通的是145,中国移动的是147等等. 虚拟运营商. 电信:1700、1701、1702.
* 移动:1703、1705、1706. 联通:1704、1707、1708、1709、171. 卫星通信:1349.
* @param phone phone
* @return boolean
*/
public static boolean isPhone(String phone) {
String regex = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$";
if (phone.length() != 11) {
log.info("手机号应为11位数");
return false;
}
else {
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(phone);
boolean isMatch = m.matches();
if (!isMatch) {
log.info("手机号格式不正确");
}
return isMatch;
}
}
/**
* 校验短信验证码.
* @param mobile mobile
* @param kaptcha kaptcha
* @return 校验结果
*/
public Boolean checkKaptcha(String mobile, String kaptcha) {
String s = this.redisClient.get(mobile);
return s != null && s.equals(kaptcha);
}
/**
* 生成短信验证码并存储.
* @return kaptcha
*/
private String getKaptcha() {
StringBuilder str = new StringBuilder();
Random random = new Random();
for (int i = 0; i < 4; i++) {
// 生成一个[0,10)
int randomInt = random.nextInt(10);
str.append(randomInt);
}
return str.toString();
}
}

浙公网安备 33010602011771号