一、阿里云短信服务介绍
短信服务(Short Message Service)是阿里云为广大企业用户或个人用户提供的通信服务。通过API/SDK、控制台调用短信发送能力,将指定信息发送至国内或境外手机号码。可以在不同场景发送不同类型的短信,例如验证码、通知短信、推广短信以及多媒体短信等。
在我们学习第三方服务调用的时候,最好是参考最新的官方文档进行学习使用,阿里云SMS短信服务官方帮助文档:https://help.aliyun.com/zh/sms/。
二、服务开通准备工作
注册阿里云账户(注册完成后需要实名认证),注册完账号之后登录阿里云https://www.aliyun.com/。
产品搜索短信服务
,点击进入短信服务
。
如果是新用户(未开通过阿里云短信服务),可以免费使用:https://free.aliyun.com/product/cloudcommunication-free-trial
以前开通过短信服务的用户,如果只是个人测试使用,发送的短信不多,可以在个人账户中充1元,因为发送一条短信是¥0.045。
1、申请资质、签名和短信模板
在 短信服务控制台 中申请资质、测试签名、测试模板。
- 在资质管理中申请资质(个人或企业)
- 在签名管理中申请签名,适用场景根据自己的需求填写。
短信签名可申请次数请参见下表:
- 在模板管理中添加短信模板,根据自己的需求填写即可,这边使用了一个双变量模板。
注意:以上申请都需要审核时间,符合规范可以更快的通过。
2、创建并保存Accesskey
在阿里云网站上的个人中心配置Accesskey,查询AccessKeyld和AccesskeySecret。
点击继续使用AccessKey。
点击创建AccessKey。
注意:通过安全验证后可以看到生成的accessKeyld和accessKeySecret,大家下载csv文件或者复制下来,因为accessKeySecret只显示一次,点击确定后将不再显示!
3、配置访问凭证AK & SK(系统环境变量)
目前最新官方SDK要求将AccessKey ID和AccessKey Secret配置到系统环境变量,才能使用阿里云OSS服务。
去官网申请和配置好AK密钥对后,就可以使用下面的工具类发送阿里云短信啦~
- 以Windows配置访问凭证为例(其他系统请参考官方文档)
以管理员身份打开CMD命令行,执行如下命令,配置系统的环境变量。
set ALIBABA_CLOUD_ACCESS_KEY_ID=yourAccessKeyId set ALIBABA_CLOUD_ACCESS_KEY_SECRET=yourAccessKeySecret
注意:将上述的ACCESS_KEY_ID 与 ACCESS_KEY_SECRET 的值要替换成自己的。
执行如下命令,让更改生效。
setx ALIBABA_CLOUD_ACCESS_KEY_ID "%ALIBABA_CLOUD_ACCESS_KEY_ID%" setx ALIBABA_CLOUD_ACCESS_KEY_SECRET "%ALIBABA_CLOUD_ACCESS_KEY_SECRET%"
执行如下命令,验证环境变量是否生效。
echo %ALIBABA_CLOUD_ACCESS_KEY_ID% echo %ALIBABA_CLOUD_ACCESS_KEY_SECRET%
注意:设置完环境变量需要重启IDEA,才能重新读取系统环境变量。
三、调用API发送短信验证码
1、导入Maven依赖坐标
<!-- 阿里云短信SMS --> <dependency> <groupId>com.aliyun</groupId> <artifactId>dysmsapi20170525</artifactId> <version>3.0.0</version> </dependency>
2、阿里云短信验证码发送工具类
- 阿里云短信验证码发送工具类SMSUtils(支持单双参数模板)
/** * 阿里云短信验证码发送工具类 */ public class SMSUtils { /** * 发送短信(双参数模板) * <phoneNumbers>: 接收短信的手机号码,多个用英文逗号隔开 * <signNameJson>: 短信签名名称,eg: "阿里云" * <templateCode>: 短信模板CODE * <templateParamJson>: 短信模板变量对应的实际值,eg:{"code":"1234"} * * @param signName 签名 * @param templateCode 模板 * @param phoneNumbers 手机号 * @param code 验证码 * @param time 验证码有效期(单位:秒) */ public static void sendMessage(String signName, String templateCode, String phoneNumbers, String code, int time) { // 初始化请求客户端 Client client = null; try { client = SMSUtils.createClient(); } catch (Exception e) { throw new RuntimeException(e); } // 构造请求对象,请填入请求参数值 SendSmsRequest sendSmsRequest = new SendSmsRequest() .setPhoneNumbers(phoneNumbers) .setSignName(signName) .setTemplateCode(templateCode) .setTemplateParam("{\"code\":\"" + code + "\",\"time\":\"" + time + "\"}"); // 获取响应对象 SendSmsResponse sendSmsResponse = null; try { sendSmsResponse = client.sendSms(sendSmsRequest); } catch (Exception e) { throw new RuntimeException(e); } // 响应包含服务端响应的 body 和 headers System.out.println(toJSONString(sendSmsResponse)); //System.out.println(sendSmsResponse.getBody()); } private static Client createClient() throws Exception { Config config = new Config() // 配置 AccessKey ID,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。 .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")) // 配置 AccessKey Secret,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。 .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")); // 配置 Endpoint config.endpoint = "dysmsapi.aliyuncs.com"; return new Client(config); } /** * 发送短信(单参数模板) * <phoneNumbers>: 接收短信的手机号码,多个用英文逗号隔开 * <signNameJson>: 短信签名名称,eg: "阿里云" * <templateCode>: 短信模板CODE * <templateParamJson>: 短信模板变量对应的实际值,eg:{"code":"1234"} * * @param signName 签名 * @param templateCode 模板 * @param phoneNumbers 手机号 * @param code 验证码 */ public static void sendMessage(String signName, String templateCode, String phoneNumbers, String code) { // 初始化请求客户端 Client client = null; try { client = SMSUtils.createClient(); } catch (Exception e) { throw new RuntimeException(e); } // 构造请求对象,请填入请求参数值 SendSmsRequest sendSmsRequest = new SendSmsRequest() .setPhoneNumbers(phoneNumbers) .setSignName(signName) .setTemplateCode(templateCode) .setTemplateParam("{\"code\":\"" + code + "\"}"); // 获取响应对象 SendSmsResponse sendSmsResponse = null; try { sendSmsResponse = client.sendSms(sendSmsRequest); } catch (Exception e) { throw new RuntimeException(e); } // 响应包含服务端响应的 body 和 headers System.out.println(toJSONString(sendSmsResponse)); } }
3、调用工具类发送短信
- 下面给出一个发送验证码的示例
@Slf4j @RestController @RequestMapping("/user") public class UserController { /** * 发送手机验证码并保存验证码到Session */ @PostMapping("/code") public Result sendCode(@RequestParam("phone") String phone, HttpSession session) { // 校验手机号格式是否有效 if (RegexUtils.isPhoneInvalid(phone)) { // 格式不符合,返回错误信息 return Result.fail("手机号格式错误!"); } // 格式有效,生成验证码 String code = RandomUtil.randomNumbers(6); // 随机6位数字 // 保存验证码到session session.setAttribute(phone, code); // 发送验证码,有效期LOGIN_CODE_TTL分钟 SMSUtils.sendMessage("签名signName", "SMS_474225xxx", phone, code, LOGIN_CODE_TTL); // 模拟发送短信验证码 log.debug("向{}发送短信验证码成功,验证码:{}", phone, code); // 返回ok return Result.ok(); } }
- 也可以直接在main()方法中调用SMSUtils.sendMessage()测试发送。
public static void main(String[] args) { sendMessage("XXX网站签名", "SMS_474225xxx", "13900010001", "6666", 5); }