阿里簡訊服務SMS
阿新 • • 發佈:2021-08-23
首先想要使用阿里簡訊服務必須獲取到阿里的AccessKey
獲取簡訊服務的簽名以及模板
SmsUtils
@Component public class SmSUtil { private static final Logger logger = LoggerFactory.getLogger(SendSmsServiceImpl.class); @Value("${aliyun.accessKeyID}") //從yml檔案中獲取到accessKeyID private String accessKeyID; @Value("${aliyun.accessKeySecret}") //從yml檔案中獲取accessKeySecret private String accessKeySecret; public boolean sendSms(String phoneNum, String code) { DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyID, accessKeySecret); IAcsClient client = new DefaultAcsClient(profile); CommonRequest request = new CommonRequest(); request.setMethod(MethodType.POST); request.setDomain("dysmsapi.aliyuncs.com"); //簡訊API產品域名(介面地址固定,無需修改) request.setVersion("2017-05-25"); //版本時間,由於阿里早期開發sdk混亂,一般使用這個版本 request.setAction("SendSms"); request.putQueryParameter("RegionId", "cn-hangzhou"); request.putQueryParameter("SignName", "XXX"); //簽名,就是從阿里簡訊服務獲取到的簽名 request.putQueryParameter("PhoneNumbers", phoneNum); //接收簡訊者的手機號 request.putQueryParameter("TemplateCode", "SMS_209190486"); //簡訊模板 傳送國際/港澳臺訊息時,請使用國際/港澳臺簡訊模版 Map<String, Object> params = new HashMap<>(); params.put("code", code); //傳送到手機的驗證碼 request.putQueryParameter("TemplateParam", JSON.toJSONString(params)); try { CommonResponse response = client.getCommonResponse(request); // System.out.println(response.getData()); // 返回的訊息 logger.info(JSON.parseObject(response.getData(), Map.class).get("Message").toString()); return response.getHttpResponse().isSuccess(); } catch (ServerException e) { e.printStackTrace(); } catch (ClientException e) { e.printStackTrace(); } return false; } }
SendSmsService
public interface SendSmsService {
/**
* 傳送簡訊驗證碼的介面
*
* @param phoneNum 手機號
* @return
*/
boolean sendSms(@Param("phoneNum") String phoneNum);
/**
* 驗證驗證碼是否正確
* @param code
* @param phone
* @return
*/
boolean checkSmsCode(String code,String phone) ;
SendSmsServiceImpl
@Service @Data public class SendSmsServiceImpl implements SendSmsService { @Resource private RedisTemplate<String, String> redisTemplate; @Resource private SmSUtil smSUtil; @Override public boolean sendSms(String phoneNum) { // 獲取到操作String的物件 ValueOperations<String, String> stringR = redisTemplate.opsForValue(); // 根據手機號進行查詢 String phone = stringR.get(phoneNum); // 如果手機號在redis中不存在的話才進行傳送驗證碼操作 if (StringUtils.isEmpty(phone)) { // 生成6位隨機數 String securityCode = String.valueOf(Math.random()).substring(3, 9); // 呼叫業務層介面 傳送驗證碼 boolean sendSmsFlag = smSUtil.sendSms(phoneNum, securityCode); if (sendSmsFlag) { // 傳送成功之後往redis中存入該手機號以及驗證碼 並設定超時時間 5 分鐘 stringR.set(phoneNum, securityCode, 5, TimeUnit.MINUTES); } return true; } else { return false; } } @Override public boolean checkSmsCode(String code, String phone) { // 獲取到操作String的物件 ValueOperations<String, String> stringR = redisTemplate.opsForValue(); // 根據Key進行查詢 String redisCode = stringR.get(phone); if (StringUtils.isEmpty(redisCode)) { return false; } if (code.equals(redisCode)) { return true; } return false; } }
SendSmsController
@RestController
@AllArgsConstructor
@RequestMapping("sms")
@Api(value = "簡訊驗證", tags = "簡訊驗證")
@CrossOrigin // 跨域支援
public class SendSmsController {
@Resource
private SendSmsService sendSmsService;
@GetMapping("/sendSms")
public R sendSms(@RequestParam("phoneNum") String phoneNum) {
//驗證手機號格式是否合理存在
boolean chinaPhoneLegal = PhoneFormatCheckUtils.isChinaPhoneLegal(phoneNum);
//如果手機號格式正確,傳送簡訊,否則要求重新填寫手機號
if (chinaPhoneLegal) {
boolean result = sendSmsService.sendSms(phoneNum);
if (result) {
return R.data("傳送成功請注意檢視手機");
}
return R.fail("傳送失敗請重新嘗試");
}
return R.fail("請輸入正確的18位手機號");
}
@GetMapping("/checkCode/")
public R checkCode(String phone, String code) {
boolean result = sendSmsService.checkSmsCode(code, phone);
if (result) {
return R.data("登入成功");
} else {
return R.fail("驗證碼已過期或錯誤請重試");
}
}
}
注意阿里雲中的AccessKey,簡訊服務簽名以及簡訊模板一定要稽核通過正確
另外,一個小時內同一個手機號簡訊只能收到5次,會報
觸發小時級流控Permits:5