阿里短信服务SMS

首先想要使用阿里短信服务必须获取到阿里的AccessKey

image-20210818104606900

1629255325(1)

获取短信服务的签名以及模板

1629255466(1)

1629255593(1)

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
posted @ 2021-08-23 14:12  fkxiaozhou  阅读(920)  评论(0编辑  收藏  举报