后端消息消息-短信
cmyang1. 短信平台
2. 购买短信
个人开发或者测试可以接入第三方厂商,费用很低,不需要审核
https://market.aliyun.com/products/57000002/cmapi00046920.html
购买3元75条和0元5条测试
购买成功后,打开地址,查看订单和开发需要用到的AppKey,AppSecret,AppCode
3. 代码接入
3.1 配置文件
1 2 3 4
| sms: app-code: 订单中的AppCode template-id: M72CB42894
|
3.2 短信配置类
1 2 3 4 5 6 7 8 9 10
| @ConfigurationProperties(prefix = "sms") @Configuration @Data public class SmsConfig {
private String appCode;
private String templateId;
}
|
3.3 HTTP发送配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Configuration public class RestTemplateConfig {
@Bean public RestTemplate restTemplate(ClientHttpRequestFactory factory) { return new RestTemplate(factory); }
@Bean public ClientHttpRequestFactory simpleClientHttpRequestFactory() { SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); factory.setReadTimeout(3000); factory.setConnectTimeout(3000); return factory; } }
|
3.4 发送短信
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| @Component @Slf4j public class SmsComponent {
@Autowired private RestTemplate restTemplate; @Autowired private SmsConfig smsConfig;
private static final String URL_TEMPLATE = "https://jmsms.market.alicloudapi.com/sms/send?mobile=%s&templateId=%s&value=%s";
public void send(String to, String value) { String url = String.format(URL_TEMPLATE, to, smsConfig.getTemplateId(), value); HttpHeaders headers = new HttpHeaders(); headers.set("Authorization", "APPCODE " + smsConfig.getAppCode()); HttpEntity<String> entity = new HttpEntity<>(headers); ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class); if (response.getStatusCode() == HttpStatus.OK) { log.info("发送短信成功,响应信息:{}", response.getBody()); } else { log.error("发送短信失败,响应信息:{}:{}", response.getStatusCode(), response.getBody()); } } }
|
3.5 单元测试
1 2 3 4 5 6 7 8 9 10 11
| @SpringBootTest public class AccountTest {
@Autowired private SmsComponent smsComponent;
@Test void sendTest() { smsComponent.send("18566668888", "666888"); } }
|
3.6 短信验证码失效时间
开发中短信验证码,一般有两个过期时间,一个是60秒防止重复发送,一个验证码10分钟有效,通过一个redis的key来判断,可以通过过期时间差来判断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| private static final Long CODE_EXPIRE_SECONDS = 600L;
public JsonData sendCode(SendCodeEnum sendCodeEnum, String to) { String cacheKey = String.format(RedisKey.CHECK_CODE_KEY, sendCodeEnum.name(), to); Long expireSeconds = stringRedisTemplate.getExpire(cacheKey, TimeUnit.SECONDS); if(CODE_EXPIRE_SECONDS - expireSeconds < 60) { return JsonData.buildResult(BizCodeEnum.CODE_LIMITED); } String code = CommonUtil.getRandomCode(6); stringRedisTemplate.opsForValue().set(cacheKey, code, CODE_EXPIRE_SECONDS, TimeUnit.SECONDS); if(CheckUtil.isEmail(to)) { } else if(CheckUtil.isPhone(to)) { smsComponent.send(to, smsConfig.getTemplateId(), code); } return JsonData.buildSuccess(); }
|