国际验证码以及手机验证码登录

This commit is contained in:
cnc
2026-09-18 09:44:26 +08:00
parent 926426fe4f
commit e0524d17eb
11 changed files with 296 additions and 22 deletions

View File

@@ -23,11 +23,27 @@
<artifactId>sms4j-spring-boot-starter</artifactId>
</dependency>
<!-- 阿里云国际短信 SDK -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dysmsapi20180501</artifactId>
</dependency>
<!-- 阿里云 OpenAPI 基础包(提供 com.aliyun.teaopenapi.models.Config,显式声明避免仅靠传递依赖) -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>tea-openapi</artifactId>
</dependency>
<!-- RuoYi Common Redis-->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-redis</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
</dependencies>

View File

@@ -0,0 +1,37 @@
package org.dromara.common.sms.config;
import com.aliyun.dysmsapi20180501.Client;
import com.aliyun.teaopenapi.models.Config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
/**
* 阿里云国际短信自动配置
*
* @author ruoyi
*/
@Slf4j
@AutoConfiguration
@EnableConfigurationProperties(AliyunInternationalSmsProperties.class)
@ConditionalOnProperty(prefix = "aliyun.international-sms", name = "enabled", havingValue = "true")
public class AliyunInternationalSmsAutoConfiguration {
/**
* 构建阿里云国际短信客户端
*
* @param properties 国际短信配置
* @return 短信客户端
*/
@Bean
public Client dysmsapi20180501Client(AliyunInternationalSmsProperties properties) throws Exception {
Config config = new Config()
.setAccessKeyId(properties.getAccessKeyId())
.setAccessKeySecret(properties.getAccessKeySecret());
config.endpoint = properties.getEndpoint();
return new Client(config);
}
}

View File

@@ -0,0 +1,40 @@
package org.dromara.common.sms.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* 阿里云国际短信配置属性
*
* @author ruoyi
*/
@Data
@ConfigurationProperties(prefix = "aliyun.international-sms")
public class AliyunInternationalSmsProperties {
/**
* 是否启用
*/
private Boolean enabled = false;
/**
* 阿里云国际站 AccessKeyId
*/
private String accessKeyId;
/**
* 阿里云国际站 AccessKeySecret
*/
private String accessKeySecret;
/**
* 接入点,国际短信固定为 dysmsapi.ap-southeast-1.aliyuncs.com
*/
private String endpoint = "dysmsapi.ap-southeast-1.aliyuncs.com";
/**
* 发件人标识 SenderId(部分国家/地区需报备)
*/
private String senderId;
}

View File

@@ -0,0 +1,60 @@
package org.dromara.common.sms.core;
import com.aliyun.dysmsapi20180501.Client;
import com.aliyun.dysmsapi20180501.models.SendMessageToGlobeRequest;
import com.aliyun.dysmsapi20180501.models.SendMessageToGlobeResponse;
import com.aliyun.dysmsapi20180501.models.SendMessageToGlobeResponseBody;
import com.aliyun.teautil.models.RuntimeOptions;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.sms.config.AliyunInternationalSmsProperties;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
/**
* 阿里云国际短信发送服务
*
* @author ruoyi
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class AliyunInternationalSmsService {
private final Client dysmsapi20180501Client;
private final AliyunInternationalSmsProperties properties;
/**
* 向境外手机号发送短信
*
* @param to 国际号码,带国家码且不含 + / 00 前缀,例如 62895111666
* @param message 短信内容(国际短信可自由编辑)
* @return 发送结果
*/
public SendMessageToGlobeResponseBody sendMessageToGlobe(String to, String message) {
log.info("国际短信发送开始, 手机号={}, message={}", to, message);
SendMessageToGlobeRequest request = new SendMessageToGlobeRequest()
.setTo(to)
.setMessage("您的验证码为:" + message + ",请勿泄露于他人!");
if (StringUtils.hasText(properties.getSenderId())) {
request.setChannelId(properties.getSenderId());
}
try {
SendMessageToGlobeResponse response = dysmsapi20180501Client
.sendMessageToGlobeWithOptions(request, new RuntimeOptions());
SendMessageToGlobeResponseBody body = response.getBody();
if (body == null || !"OK".equalsIgnoreCase(body.getResponseCode())) {
log.error("国际短信发送失败, to={}, body={}", to, body);
throw new ServiceException("国际短信发送失败:" + (body == null ? "无响应" : body.getResponseCode()));
}
return body;
} catch (ServiceException e) {
throw e;
} catch (Exception e) {
log.error("国际短信发送异常, to={}", to, e);
throw new ServiceException("国际短信发送异常:" + e.getMessage());
}
}
}

View File

@@ -1 +1,2 @@
org.dromara.common.sms.config.SmsAutoConfiguration
org.dromara.common.sms.config.AliyunInternationalSmsAutoConfiguration