zoukankan      html  css  js  c++  java
  • 阿里短信服务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
    
  • 相关阅读:
    WPF中样式中事件处理
    模板方法
    WPF 中ComboBox绑定DataSet
    装饰模式
    【转帖】c#项目的打包部署教材图文
    WPF中用比例设置长度或宽度
    在WFP中完美使用winform的控件
    一个WPF软件作品新鲜出炉,欢迎拍砖
    建造者模式(生成器模式)
    Windows Presentation Foundation 中的 Pack URI
  • 原文地址:https://www.cnblogs.com/fkxiaozhou/p/15175653.html
Copyright © 2011-2022 走看看