1. 程式人生 > 其它 >阿里簡訊服務SMS

阿里簡訊服務SMS

首先想要使用阿里簡訊服務必須獲取到阿里的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