AliSmsService.java 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package com.izouma.nineth.service.sms;
  2. import com.aliyuncs.CommonRequest;
  3. import com.aliyuncs.CommonResponse;
  4. import com.aliyuncs.DefaultAcsClient;
  5. import com.aliyuncs.IAcsClient;
  6. import com.aliyuncs.exceptions.ClientException;
  7. import com.aliyuncs.http.MethodType;
  8. import com.aliyuncs.profile.DefaultProfile;
  9. import com.izouma.nineth.config.Constants;
  10. import com.izouma.nineth.domain.SmsRecord;
  11. import com.izouma.nineth.exception.BusinessException;
  12. import com.izouma.nineth.repo.SmsRecordRepo;
  13. import io.jsonwebtoken.Jwts;
  14. import io.jsonwebtoken.SignatureAlgorithm;
  15. import lombok.extern.slf4j.Slf4j;
  16. import org.apache.commons.lang3.RandomStringUtils;
  17. import org.springframework.beans.factory.annotation.Autowired;
  18. import org.springframework.beans.factory.annotation.Value;
  19. import org.springframework.boot.configurationprocessor.json.JSONException;
  20. import org.springframework.boot.configurationprocessor.json.JSONObject;
  21. import org.springframework.stereotype.Service;
  22. import java.time.LocalDateTime;
  23. import java.time.ZoneOffset;
  24. import java.util.Date;
  25. import java.util.HashMap;
  26. @Service
  27. @Slf4j
  28. public class AliSmsService implements SmsService {
  29. @Value("${aliyun.access-key-id}")
  30. private String accessKeyId;
  31. @Value("${aliyun.access-key-secret}")
  32. private String accessKeySecret;
  33. @Value("${aliyun.sms-sign}")
  34. private String smsSign;
  35. @Value("${aliyun.sms-code}")
  36. private String smsCode;
  37. @Autowired
  38. private SmsRecordRepo smsRecordRepo;
  39. @Override
  40. public String sendVerify(String phone) {
  41. if (smsSign.equals("身份验证")) {
  42. accessKeyId = "LTAI5tEL3wr9XeiyseqKLrEK";
  43. accessKeySecret = "I9JzOThjzeJMcpVf6melaMY3nt7ucU";
  44. }
  45. smsRecordRepo.findLastByPhoneAndExpiresAtAfterAndExpiredFalse(phone, LocalDateTime.now()).ifPresent(record -> {
  46. if (record.getCreatedAt().plusMinutes(1L).isAfter(LocalDateTime.now())) {
  47. long sec = record.getCreatedAt().plusMinutes(1L).toInstant(ZoneOffset.UTC)
  48. .getEpochSecond() - LocalDateTime.now().toInstant(ZoneOffset.UTC).getEpochSecond() + 1;
  49. throw new BusinessException("请" + sec + "秒后再试");
  50. }
  51. });
  52. String code = RandomStringUtils.randomNumeric(4);
  53. DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
  54. IAcsClient client = new DefaultAcsClient(profile);
  55. CommonRequest request = new CommonRequest();
  56. request.setMethod(MethodType.POST);
  57. request.setDomain("dysmsapi.aliyuncs.com");
  58. request.setVersion("2017-05-25");
  59. request.setAction("SendSms");
  60. request.putQueryParameter("PhoneNumbers", phone);
  61. request.putQueryParameter("SignName", smsSign);
  62. request.putQueryParameter("TemplateCode", smsCode);
  63. if (smsSign.equals("身份验证")) {
  64. request.putQueryParameter("TemplateParam", "{\"code\":\"" + code + "\",\"product\":\"用户\"}");
  65. } else {
  66. request.putQueryParameter("TemplateParam", "{\"code\":\"" + code + "\"}");
  67. }
  68. try {
  69. CommonResponse response = client.getCommonResponse(request);
  70. if (response.getHttpStatus() != 200) {
  71. throw new BusinessException("发送失败,请稍后再试", response.getHttpStatus() + "," + response.getData());
  72. }
  73. log.info("send sms response {}", response.getData());
  74. JSONObject jsonObject = new JSONObject(response.getData());
  75. if (!"ok".equalsIgnoreCase(jsonObject.getString("Code"))) {
  76. throw new BusinessException("发送失败,请稍后再试", jsonObject.getString("Message"));
  77. }
  78. smsRecordRepo.expire(phone);
  79. String sessionId = RandomStringUtils.randomAlphabetic(10);
  80. smsRecordRepo.save(SmsRecord.builder()
  81. .sessionId(sessionId)
  82. .phone(phone)
  83. .code(code)
  84. .expiresAt(LocalDateTime.now().plusMinutes(5))
  85. .expired(false)
  86. .build());
  87. return sessionId;
  88. } catch (ClientException | JSONException e) {
  89. e.printStackTrace();
  90. throw new BusinessException("发送失败,请稍后再试", e.getMessage());
  91. }
  92. }
  93. @Override
  94. public String verify(String phone, String code) {
  95. SmsRecord smsRecord = smsRecordRepo.findLastByPhoneAndExpiresAtAfterAndExpiredFalse(phone, LocalDateTime.now())
  96. .orElseThrow(new BusinessException("短信验证码错误"));
  97. if (!smsRecord.getCode().equalsIgnoreCase(code)) {
  98. throw new BusinessException("短信验证码错误");
  99. }
  100. smsRecord.setExpired(true);
  101. smsRecordRepo.save(smsRecord);
  102. return Jwts.builder()
  103. .setClaims(new HashMap<>())
  104. .setSubject(phone)
  105. .setIssuedAt(new Date())
  106. .setExpiration(new Date(new Date().getTime() + 10 * 60 * 1000)) //10min
  107. .signWith(SignatureAlgorithm.HS512, Constants.SMS_TOKEN_SECRET)
  108. .compact();
  109. }
  110. }