需求背景:
在做登录的时候,或者在做一下用户营销的时候,需要进行短信验证或者发短信消息。这里以阿里云和腾讯云的短信接口为例。给出两种方案,基于阿里云的短信和基于腾讯云的短信。
-
阿里云。工具类:
AliSendSMSUtil
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
/**
* 阿里云短信接口工具类
*
* @author:茅河野人
* @Description:
* @date:2022年11月29日
*/
public class AliSendSMSUtil {
// 自己的AK
private static final String accessKeyId = "";// 你的accessKeyId
private static final String accessKeySecret = "7";// 你的accessKeySecret
private static final String signName = "";// 签名
private static final String templateCode = "";// 短信模板
private static int code;
/**
* @Description:发送手机验证码
* @Param:需要发送的手机号码
* @return:OK表示成功,失败则返回失败信息
*/
public String senSMSUtil(String phoneNumber) {
// 设置超时时间-可自行调整
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
// 初始化ascClient需要的几个参数
final String product = "Dysmsapi";// 短信API产品名称(短信产品名固定,无需修改)
final String domain = "dysmsapi.aliyuncs.com";// 短信API产品域名(接口地址固定,无需修改)
// 初始化ascClient,暂时不支持多region(请勿修改)
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
try {
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
} catch (ClientException e) {
e.printStackTrace();
}
IAcsClient acsClient = new DefaultAcsClient(profile);
// 组装请求对象
SendSmsRequest request = new SendSmsRequest();
// 使用post提交
request.setMethod(MethodType.POST);
// 必填:待发送手机号。支持以逗号分隔的形式进行批量调用,批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,
// 验证码类型的短信推荐使用单条调用的方式;发送国际/港澳台消息时,接收号码格式为国际区号+号码,如“85200000000”
request.setPhoneNumbers(phoneNumber);
request.setSignName(signName);
// 必填:短信模板-可在短信控制台中找到,发送国际/港澳台消息时,请使用国际/港澳台短信模版
request.setTemplateCode(templateCode);
//随机生成六位验证码
code = (int) ((Math.random() * 9 + 1) * 100000);
// 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
// 友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
request.setTemplateParam("{code:" + code + "}");
// 请求失败这里会抛ClientException异常
SendSmsResponse sendSmsResponse = null;
try {
sendSmsResponse = acsClient.getAcsResponse(request);
} catch (ClientException e) {
e.printStackTrace();
return "请求失败";
}
assert sendSmsResponse.getCode() != null;
if (sendSmsResponse.getCode() == null || !sendSmsResponse.getCode().equals("OK")) {// 发送不成功
return sendSmsResponse.getMessage();
}
// 请求成功
return "OK";
}
public int getCode() {
return code;
}
/**
* 测试短信验证码
* @param args
*/
public static void main(String[] args) {
// 传入需要接收短信的手机号码
// 创建短信工具类对象用来发送短信
AliSendSMSUtil sendSMS = new AliSendSMSUtil();
// 发送短信并获取短信内容
String phoneNumber = "10086";
String result = sendSMS.senSMSUtil(phoneNumber);
// 发送不成功
if (result == null || !"OK".equals(result)) {
System.out.println("验证码发送失败");
}
// 获取验证码
int code = sendSMS.getCode();
System.out.println("您的验证码是:" + code);
}
}
-
腾讯云。工具类:
TecentSendSMSUtil
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
//导入可选配置类
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
// 导入对应SMS模块的client
import com.tencentcloudapi.sms.v20190711.SmsClient;
// 导入要请求接口对应的request response类
import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse;
/**
* 腾讯云短信接口工具类
*
* @author:茅河野人
* @Description:
* @date:2022年11月29日
*/
public class TecentSendSMSUtil {
/**
* 短信 appid
*/
public static final String SMSAPPID = "";
/**
* 腾讯云账户密钥对: secretId
*/
public static final String SMSSECREID = "";
/**
* 腾讯云账户密钥对: secretKey
*/
public static final String SMSSECREKEY = "";
/**
* SmsSdkAppid
*/
public static final String SMSSDKAPPID = "";
/**
* sms sign : sms签名
*/
public static final String SMSSIGN = "";
/**
* sms 短信模板id:
*/
public static final String SMSTEMPLATEID = "";
/**
* 放送短信信息
* @param valcode
* @param phoneNumbers
* @return
*/
public static String sendSms(String valcode, String[] phoneNumbers) {
try {
/*
* 必要步骤: 实例化一个认证对象,入参需要传入腾讯云账户密钥对secretId,secretKey。
* 这里采用的是从环境变量读取的方式,需要在环境变量中先设置这两个值。 你也可以直接在代码中写死密钥对,但是小心不要将代码复制、上传或者分享给他人,
* 以免泄露密钥对危及你的财产安全。 CAM密匙查询: https://console.cloud.tencent.com/cam/capi
*/
Credential cred = new Credential(SMSSECREID, SMSSECREKEY);
// 实例化一个http选项,可选,没有特殊需求可以跳过
HttpProfile httpProfile = new HttpProfile();
// 设置代理
// httpProfile.setProxyHost("host");
// httpProfile.setProxyPort(port);
/*
* SDK默认使用POST方法。 如果你一定要使用GET方法,可以在这里设置。GET方法无法处理一些较大的请求
*/
httpProfile.setReqMethod("POST");
/*
* SDK有默认的超时时间,非必要请不要进行调整 如有需要请在代码中查阅以获取最新的默认值
*/
httpProfile.setConnTimeout(60);
/*
* SDK会自动指定域名。通常是不需要特地指定域名的,但是如果你访问的是金融区的服务 则必须手动指定域名,例如sms的上海金融区域名:
* sms.ap-shanghai-fsi.tencentcloudapi.com
*/
httpProfile.setEndpoint("sms.tencentcloudapi.com");
/*
* 非必要步骤: 实例化一个客户端配置对象,可以指定超时时间等配置
*/
ClientProfile clientProfile = new ClientProfile();
/*
* SDK默认用TC3-HMAC-SHA256进行签名 非必要请不要修改这个字段
*/
clientProfile.setSignMethod("HmacSHA256");
clientProfile.setHttpProfile(httpProfile);
/*
* 实例化要请求产品(以sms为例)的client对象 第二个参数是地域信息,可以直接填写字符串ap-guangzhou,或者引用预设的常量
*/
SmsClient client = new SmsClient(cred, "ap-guangzhou", clientProfile);
/*
* 实例化一个请求对象,根据调用的接口和实际情况,可以进一步设置请求参数 你可以直接查询SDK源码确定接口有哪些属性可以设置
* 属性可能是基本类型,也可能引用了另一个数据结构 推荐使用IDE进行开发,可以方便的跳转查阅各个接口和数据结构的文档说明
*/
SendSmsRequest req = new SendSmsRequest();
/*
* 填充请求参数,这里request对象的成员变量即对应接口的入参 你可以通过官网接口文档或跳转到request对象的定义处查看请求参数的定义
* 基本类型的设置: 帮助链接: 短信控制台: https://console.cloud.tencent.com/sms/smslist sms
* helper: https://cloud.tencent.com/document/product/382/3773
*/
/* 短信应用ID: 短信SdkAppid在 [短信控制台] 添加应用后生成的实际SdkAppid,示例如1400006666 */
String appid = SMSAPPID;
req.setSmsSdkAppid(appid);
/* 短信签名内容: 使用 UTF-8 编码,必须填写已审核通过的签名,签名信息可登录 [短信控制台] 查看 */
String sign = SMSSIGN;
req.setSign(sign);
/* 国际/港澳台短信 senderid: 国内短信填空,默认未开通,如需开通请联系 [sms helper] */
// String senderid = "xxx";
// req.setSenderId(senderid);
/* 用户的 session 内容: 可以携带用户侧 ID 等上下文信息,server 会原样返回 */
// String session = "xxx";
// req.setSessionContext(session);
/* 短信码号扩展号: 默认未开通,如需开通请联系 [sms helper] */
// String extendcode = "xxx";
// req.setExtendCode(extendcode);
/* 模板 ID: 必须填写已审核通过的模板 ID。模板ID可登录 [短信控制台] 查看 */
String templateID = SMSTEMPLATEID;
req.setTemplateID(templateID);
/*
* 下发手机号码,采用 e.164 标准,+[国家或地区码][手机号] 示例如:+8613711112222, 其中前面有一个+号
* ,86为国家码,13711112222为手机号,最多不要超过200个手机号
*/
// String[] phoneNumbers = {"+8621212313123", "+8612345678902", "+8612345678903"};
req.setPhoneNumberSet(phoneNumbers);
/* 模板参数: 若无模板参数,则设置为空 */
String[] templateParams = { valcode };
req.setTemplateParamSet(templateParams);
/*
* 通过 client 对象调用 SendSms 方法发起请求。注意请求方法名与请求对象是对应的 返回的 res 是一个 SendSmsResponse
* 类的实例,与请求对象对应
*/
SendSmsResponse res = client.SendSms(req);
// 输出json格式的字符串回包
System.out.println(SendSmsResponse.toJsonString(res));
// 也可以取出单个值,你可以通过官网接口文档或跳转到response对象的定义处查看返回字段的定义
// System.out.println(res.getRequestId());
} catch (TencentCloudSDKException e) {
e.printStackTrace();
}
return null;
}
/**
* 测试
* @param args
*/
public static void main(String[] args) {
TecentSendSMSUtil.sendSms("1234", new String[] {"86***********"});
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/615e4bb59cdab052770981153ab61adf.png)
--------------------------------
方法二
在Java开发中,实现登录时的短信验证和发送短信功能需要几个关键步骤。以下是一个简化的流程和代码示例,说明如何实现这一功能:
- 选择短信服务提供商:首先,你需要选择一个可靠的短信服务提供商。有许多第三方服务提供商提供此类服务,如Twilio、Nexmo等。
- 集成短信服务提供商的SDK:大多数服务提供商会提供SDK或API供你集成到你的Java项目中。按照他们的文档进行集成。
- 发送验证短信:当用户尝试登录时,生成一个唯一的验证码并发送到用户的手机。
- 验证输入的验证码:用户输入他们在手机上收到的验证码,然后与服务器上存储的验证码进行比较。
以下是一个简化的示例代码,展示如何使用Twilio作为短信服务提供商来发送和验证验证码:
1. 集成Twilio SDK
首先,你需要在你的项目中集成Twilio的Java SDK。你可以通过Maven或Gradle来添加依赖。
例如,在pom.xml
中添加依赖:
<dependency>
<groupId>com.twilio</groupId>
<artifactId>twilio</artifactId>
<version>最新版本</version>
</dependency>
2. 发送验证短信
使用Twilio的Java SDK发送验证短信:
import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.Message;
import com.twilio.type.PhoneNumber;
public class SmsSender {
private static final String ACCOUNT_SID = "你的Twilio账号SID";
private static final String AUTH_TOKEN = "你的Twilio认证令牌";
private static final String FROM_NUMBER = "你的Twilio电话号码";
private static final String TO_NUMBER = "用户的手机号码";
public static void sendVerificationCode(String code) {
Twilio.init(ACCOUNT_SID, AUTH_TOKEN);
Message message = Message.creator(new PhoneNumber(TO_NUMBER), new PhoneNumber(FROM_NUMBER), code).create();
System.out.println(message.getSid());
}
}
3. 验证输入的验证码
验证用户输入的验证码是否与服务器上存储的验证码匹配:
public class VerificationService {
public boolean verifyCode(String inputCode, String storedCode) {
return inputCode.equals(storedCode);
}
}
4. 整合到登录流程中
最后,在用户尝试登录时,发送验证码并验证它:
public void loginUser(String phoneNumber, String inputCode) {
String verificationCode = generateVerificationCode(); // 生成验证码的方法
SmsSender.sendVerificationCode(verificationCode); // 发送验证码到用户手机
VerificationService verificationService = new VerificationService();
if (verificationService.verifyCode(inputCode, verificationCode)) {
// 验证码正确,允许用户登录
} else {
// 验证码错误,拒绝用户登录或重新发送验证码
}
}