You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
57 lines
2.9 KiB
57 lines
2.9 KiB
package com.mydreamjob.auth.sms;
|
|
|
|
import com.aliyun.dysmsapi20170525.Client;
|
|
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
|
|
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
|
|
import com.aliyun.teautil.models.RuntimeOptions;
|
|
import com.mydreamjob.common.exception.BusinessException;
|
|
import com.mydreamjob.common.exception.ErrorCode;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
import java.util.Set;
|
|
|
|
/** SDK 返回 OK 只代表网关受理,不代表手机已收到;禁止自动重试非幂等发送。 */
|
|
public final class AliyunSmsCodeSender implements SmsCodeSender {
|
|
private static final Logger LOG = LoggerFactory.getLogger(AliyunSmsCodeSender.class);
|
|
private static final Set<String> PURPOSES = Set.of("login", "password-set", "password-reset", "company-register");
|
|
private final Client client;
|
|
private final String signName;
|
|
private final String templateCode;
|
|
private final int connectTimeoutMs;
|
|
private final int readTimeoutMs;
|
|
|
|
public AliyunSmsCodeSender(Client client, AliyunSmsProperties properties) {
|
|
properties.validateForSending();
|
|
this.client = client;
|
|
this.signName = properties.getSignName();
|
|
this.templateCode = properties.getTemplateCode();
|
|
this.connectTimeoutMs = properties.getConnectTimeoutMs();
|
|
this.readTimeoutMs = properties.getReadTimeoutMs();
|
|
}
|
|
|
|
@Override
|
|
public void sendVerificationCode(String phone, String purpose, String code) {
|
|
if (phone == null || !phone.matches("[0-9]{11}") || purpose == null || !PURPOSES.contains(purpose)
|
|
|| code == null || !code.matches("[0-9]{6}")) {
|
|
throw new BusinessException(ErrorCode.BAD_REQUEST, "invalid SMS request");
|
|
}
|
|
SendSmsRequest request = new SendSmsRequest().setPhoneNumbers(phone).setSignName(signName)
|
|
.setTemplateCode(templateCode).setTemplateParam("{\"code\":\"" + code + "\"}");
|
|
RuntimeOptions runtime = new RuntimeOptions().setAutoretry(false)
|
|
.setConnectTimeout(connectTimeoutMs).setReadTimeout(readTimeoutMs);
|
|
SendSmsResponse response;
|
|
try {
|
|
response = client.sendSmsWithOptions(request, runtime);
|
|
} catch (Exception ignored) {
|
|
if (ignored instanceof InterruptedException) Thread.currentThread().interrupt();
|
|
// SDK 异常可能包含请求绑定值,既不透传原因也不输出堆栈。
|
|
LOG.warn("Aliyun SMS gateway call failed");
|
|
throw new BusinessException(ErrorCode.SMS_SEND_FAILED);
|
|
}
|
|
if (response == null || response.getBody() == null || response.getStatusCode() == null
|
|
|| response.getStatusCode() != 200 || !"OK".equals(response.getBody().getCode())) {
|
|
LOG.warn("Aliyun SMS gateway did not accept request");
|
|
throw new BusinessException(ErrorCode.SMS_SEND_FAILED);
|
|
}
|
|
}
|
|
}
|
|
|