【Springboot】| 阿里云发送短信验证码,你会了吗?

目录

? 题外话

狮子之前发了一篇《邮箱发送验证码,你会了吗?》,很快上了热度榜单,但是那篇文章只是简单介绍了如何接收验证码的流程以及安利了一个接收验证码的工具类,并没有详细介绍在项目中如何具体操作,不少人来咨询具体操作的流程,今天给大家介绍一下如何使用阿里云短信接收验证码功能。

? 需要准备的东西

我们先进入阿里云官网:next.api.aliyun.com/,点击如下:
在这里插入图片描述
在这里插入图片描述
点击快速学习和测试,进入使用界面:
在这里插入图片描述

阿里云tips:
若您的应用未上线,或网站域名未备案,或学习并体验使用阿里云通信短信服务,可以在下方「发送测试」模块,使用自定义测试签名/模板新功能
要完成发送体验,首先需完成自定义测试签名/模板的申请并审核通过,其次绑定测试手机号码。

意思就是咱们这种自己写的小项目只能使用它自带的模板!!!
点击如下图所示顺序:

在这里插入图片描述
到了下面这一步,就完成了所需要准备的东西。开始敲代码叭!
在这里插入图片描述


? 进入主题

1. 添加依赖

回到项目,添加阿里云依赖,这个依赖就在SDK示例那里!

<!-- 阿里短信平台 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dysmsapi20170525</artifactId>
<version>2.0.23</version>
</dependency>
        <!-- 阿里短信平台 -->
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>dysmsapi20170525</artifactId>
            <version>2.0.23</version>
        </dependency>
<!-- 阿里短信平台 --> <dependency> <groupId>com.aliyun</groupId> <artifactId>dysmsapi20170525</artifactId> <version>2.0.23</version> </dependency>

2. 配置yaml文件

这里没有想配置邮箱验证码那么复杂,这里只需要自定义两个变量来存储accessKeyId和accessKeySecret就行!!!

message:
accessKeyId: LTAI5tQJFQHEnxxxxxxEMSogoC
accessKeySecret: LZa3EGVR0XjS3KvvqxxxxxW5TNtbl
message:
  accessKeyId: LTAI5tQJFQHEnxxxxxxEMSogoC
  accessKeySecret: LZa3EGVR0XjS3KvvqxxxxxW5TNtbl
message: accessKeyId: LTAI5tQJFQHEnxxxxxxEMSogoC accessKeySecret: LZa3EGVR0XjS3KvvqxxxxxW5TNtbl

3. 创建阿里云客户端

这里是阿里云sdk实例自带的代码,咱们将其cv过来封装一下:

/**
* 使用AK&SK初始化账号Client
* @param accessKeyId
* @param accessKeySecret
* @return Client
* @throws Exception
*/
@SneakyThrows
public Client createClient(String accessKeyId, String accessKeySecret){
Config config = new Config()
// 必填,您的 AccessKey ID
.setAccessKeyId(accessKeyId)
// 必填,您的 AccessKey Secret
.setAccessKeySecret(accessKeySecret);
// 访问的域名
config.endpoint = "dysmsapi.aliyuncs.com";
return new Client(config);
}
    /**
     * 使用AK&SK初始化账号Client
     * @param accessKeyId
     * @param accessKeySecret
     * @return Client
     * @throws Exception
     */

    @SneakyThrows
    public Client createClient(String accessKeyId, String accessKeySecret){
        Config config = new Config()
                // 必填,您的 AccessKey ID
                .setAccessKeyId(accessKeyId)
                // 必填,您的 AccessKey Secret
                .setAccessKeySecret(accessKeySecret);
        // 访问的域名
        config.endpoint = "dysmsapi.aliyuncs.com";
        return new Client(config);
    }
/** * 使用AK&SK初始化账号Client * @param accessKeyId * @param accessKeySecret * @return Client * @throws Exception */ @SneakyThrows public Client createClient(String accessKeyId, String accessKeySecret){ Config config = new Config() // 必填,您的 AccessKey ID .setAccessKeyId(accessKeyId) // 必填,您的 AccessKey Secret .setAccessKeySecret(accessKeySecret); // 访问的域名 config.endpoint = "dysmsapi.aliyuncs.com"; return new Client(config); }

4. 编写发送短信方法

这里也是通过cvSDK实例代码封装:

/**
* 发送短信
*
* @param phoneNumber 手机号
* @param code 验证码
* @return 返回结果
*/
@Override
@SneakyThrows
public BaseResult sendMessage(String phoneNumber, String code) {
// 工程代码泄露可能会导致AccessKey泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378657.html
Client client = createClient(accessKeyId, accessKeySecret);
SendSmsRequest sendSmsRequest = new SendSmsRequest()
.setSignName("阿里云短信测试")
.setTemplateCode("SMS_154xxxx09")
.setPhoneNumbers("1392xxxx410")
.setTemplateParam("{\"code\":\""+code+"\"}");
RuntimeOptions runtime = new RuntimeOptions();
// 复制代码运行请自行打印 API 的返回值
SendSmsResponse response = client.sendSmsWithOptions(sendSmsRequest, runtime);
SendSmsResponseBody body = response.getBody();
String code1 = body.getCode();
if ("OK".equals(code1)){
return BaseResult.ok();
}
return new BaseResult(500,body.getMessage(),null);
}
  /**
     * 发送短信
     *
     * @param phoneNumber 手机号
     * @param code        验证码
     * @return 返回结果
     */

    @Override
    @SneakyThrows
    public BaseResult sendMessage(String phoneNumber, String code) {
        // 工程代码泄露可能会导致AccessKey泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378657.html
            Client client = createClient(accessKeyId, accessKeySecret);
            SendSmsRequest sendSmsRequest = new SendSmsRequest()
                    .setSignName("阿里云短信测试")
                    .setTemplateCode("SMS_154xxxx09")
                    .setPhoneNumbers("1392xxxx410")
                    .setTemplateParam("{\"code\":\""+code+"\"}");
            RuntimeOptions runtime = new RuntimeOptions();
            // 复制代码运行请自行打印 API 的返回值
        SendSmsResponse response = client.sendSmsWithOptions(sendSmsRequest, runtime);
        SendSmsResponseBody body = response.getBody();
        String code1 = body.getCode();
        if ("OK".equals(code1)){
            return BaseResult.ok();
        }

        return new BaseResult(500,body.getMessage(),null);
    }
/** * 发送短信 * * @param phoneNumber 手机号 * @param code 验证码 * @return 返回结果 */ @Override @SneakyThrows public BaseResult sendMessage(String phoneNumber, String code) { // 工程代码泄露可能会导致AccessKey泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378657.html Client client = createClient(accessKeyId, accessKeySecret); SendSmsRequest sendSmsRequest = new SendSmsRequest() .setSignName("阿里云短信测试") .setTemplateCode("SMS_154xxxx09") .setPhoneNumbers("1392xxxx410") .setTemplateParam("{\"code\":\""+code+"\"}"); RuntimeOptions runtime = new RuntimeOptions(); // 复制代码运行请自行打印 API 的返回值 SendSmsResponse response = client.sendSmsWithOptions(sendSmsRequest, runtime); SendSmsResponseBody body = response.getBody(); String code1 = body.getCode(); if ("OK".equals(code1)){ return BaseResult.ok(); } return new BaseResult(500,body.getMessage(),null); }

5. 完整代码展示

import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.dysmsapi20170525.models.SendSmsResponseBody;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.lion.result.BaseResult;
import lombok.SneakyThrows;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service
public class MessageServiceImpl implements MessageService {
@Value("${message.accessKeyId}")
private String accessKeyId;
@Value("${message.accessKeySecret}")
private String accessKeySecret;
/**
* 使用AK&SK初始化账号Client
* @param accessKeyId
* @param accessKeySecret
* @return Client
* @throws Exception
*/
@SneakyThrows
public Client createClient(String accessKeyId, String accessKeySecret){
Config config = new Config()
// 必填,您的 AccessKey ID
.setAccessKeyId(accessKeyId)
// 必填,您的 AccessKey Secret
.setAccessKeySecret(accessKeySecret);
// 访问的域名
config.endpoint = "dysmsapi.aliyuncs.com";
return new Client(config);
}
/**
* 发送短信
*
* @param phoneNumber 手机号
* @param code 验证码
* @return 返回结果
*/
@Override
@SneakyThrows
public BaseResult sendMessage(String phoneNumber, String code) {
// 工程代码泄露可能会导致AccessKey泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378657.html
Client client = createClient(accessKeyId, accessKeySecret);
SendSmsRequest sendSmsRequest = new SendSmsRequest()
.setSignName("阿里云短信测试")
.setTemplateCode("SMS_15xxx909")
.setPhoneNumbers("1392xxxx410")
.setTemplateParam("{\"code\":\""+code+"\"}");
RuntimeOptions runtime = new RuntimeOptions();
// 复制代码运行请自行打印 API 的返回值
SendSmsResponse response = client.sendSmsWithOptions(sendSmsRequest, runtime);
SendSmsResponseBody body = response.getBody();
String code1 = body.getCode();
if ("OK".equals(code1)){
return BaseResult.ok();
}
return new BaseResult(500,body.getMessage(),null);
}
}
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.dysmsapi20170525.models.SendSmsResponseBody;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.lion.result.BaseResult;
import lombok.SneakyThrows;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class MessageServiceImpl implements MessageService {
    @Value("${message.accessKeyId}")
    private String accessKeyId;
    @Value("${message.accessKeySecret}")
    private String accessKeySecret;

    /**
     * 使用AK&SK初始化账号Client
     * @param accessKeyId
     * @param accessKeySecret
     * @return Client
     * @throws Exception
     */
    @SneakyThrows
    public Client createClient(String accessKeyId, String accessKeySecret){
        Config config = new Config()
                // 必填,您的 AccessKey ID
                .setAccessKeyId(accessKeyId)
                // 必填,您的 AccessKey Secret
                .setAccessKeySecret(accessKeySecret);
        // 访问的域名
        config.endpoint = "dysmsapi.aliyuncs.com";
        return new Client(config);
    }



    /**
     * 发送短信
     *
     * @param phoneNumber 手机号
     * @param code        验证码
     * @return 返回结果
     */
    @Override
    @SneakyThrows
    public BaseResult sendMessage(String phoneNumber, String code) {
        // 工程代码泄露可能会导致AccessKey泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378657.html
            Client client = createClient(accessKeyId, accessKeySecret);
            SendSmsRequest sendSmsRequest = new SendSmsRequest()
                    .setSignName("阿里云短信测试")
                    .setTemplateCode("SMS_15xxx909")
                    .setPhoneNumbers("1392xxxx410")
                    .setTemplateParam("{\"code\":\""+code+"\"}");
            RuntimeOptions runtime = new RuntimeOptions();
            // 复制代码运行请自行打印 API 的返回值
        SendSmsResponse response = client.sendSmsWithOptions(sendSmsRequest, runtime);
        SendSmsResponseBody body = response.getBody();
        String code1 = body.getCode();
        if ("OK".equals(code1)){
            return BaseResult.ok();
        }
        return new BaseResult(500,body.getMessage(),null);
    }
}
import com.aliyun.dysmsapi20170525.Client; import com.aliyun.dysmsapi20170525.models.SendSmsRequest; import com.aliyun.dysmsapi20170525.models.SendSmsResponse; import com.aliyun.dysmsapi20170525.models.SendSmsResponseBody; import com.aliyun.teaopenapi.models.Config; import com.aliyun.teautil.models.RuntimeOptions; import com.lion.result.BaseResult; import lombok.SneakyThrows; import org.apache.dubbo.config.annotation.DubboService; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @Service public class MessageServiceImpl implements MessageService { @Value("${message.accessKeyId}") private String accessKeyId; @Value("${message.accessKeySecret}") private String accessKeySecret; /** * 使用AK&SK初始化账号Client * @param accessKeyId * @param accessKeySecret * @return Client * @throws Exception */ @SneakyThrows public Client createClient(String accessKeyId, String accessKeySecret){ Config config = new Config() // 必填,您的 AccessKey ID .setAccessKeyId(accessKeyId) // 必填,您的 AccessKey Secret .setAccessKeySecret(accessKeySecret); // 访问的域名 config.endpoint = "dysmsapi.aliyuncs.com"; return new Client(config); } /** * 发送短信 * * @param phoneNumber 手机号 * @param code 验证码 * @return 返回结果 */ @Override @SneakyThrows public BaseResult sendMessage(String phoneNumber, String code) { // 工程代码泄露可能会导致AccessKey泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378657.html Client client = createClient(accessKeyId, accessKeySecret); SendSmsRequest sendSmsRequest = new SendSmsRequest() .setSignName("阿里云短信测试") .setTemplateCode("SMS_15xxx909") .setPhoneNumbers("1392xxxx410") .setTemplateParam("{\"code\":\""+code+"\"}"); RuntimeOptions runtime = new RuntimeOptions(); // 复制代码运行请自行打印 API 的返回值 SendSmsResponse response = client.sendSmsWithOptions(sendSmsRequest, runtime); SendSmsResponseBody body = response.getBody(); String code1 = body.getCode(); if ("OK".equals(code1)){ return BaseResult.ok(); } return new BaseResult(500,body.getMessage(),null); } }

6. 测试

我们先来测试一下短信发送,在测试类里面编写:

@Autowired
MessageService messageService;
@Test
void contextLoads(){
BaseResult result = messageService.sendMessage("139xxxxxx410", "8888");
}
   @Autowired
    MessageService messageService;
    @Test
    void contextLoads(){
        BaseResult result = messageService.sendMessage("139xxxxxx410", "8888");
    }
@Autowired MessageService messageService; @Test void contextLoads(){ BaseResult result = messageService.sendMessage("139xxxxxx410", "8888"); }

测试结果
在这里插入图片描述

运行一次1s374ms,不得不说,确实是免费的东西好用(懂的都懂!)


? 场景实操

场景:接收短信验证码登录系统

  • 接收短信验证码并将其保存到redis数据库里,设置过期时间为5分钟,等待验证!

1. 编写生成验证码工具类

public class RandomUtil {
/**
* 生成验证码
* @param digit 位数
* @return
*/
public static String buildCheckCode(int digit){
String str = "0123456789";
StringBuilder sb = new StringBuilder();
Random random = new Random();
for (int i = 0; i < digit; i++) {
char ch = str.charAt(random.nextInt(str.length()));
sb.append(ch);
}
return sb.toString();
}
}
public class RandomUtil {
    /**
     * 生成验证码
     * @param digit 位数
     * @return
     */
    public static String buildCheckCode(int digit){
        String str = "0123456789";
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < digit; i++) {
            char ch = str.charAt(random.nextInt(str.length()));
            sb.append(ch);
        }
        return sb.toString();
    }
}
public class RandomUtil { /** * 生成验证码 * @param digit 位数 * @return */ public static String buildCheckCode(int digit){ String str = "0123456789"; StringBuilder sb = new StringBuilder(); Random random = new Random(); for (int i = 0; i < digit; i++) { char ch = str.charAt(random.nextInt(str.length())); sb.append(ch); } return sb.toString(); } }

2. 保存到redis操作

// 保存登录验证码到redis
@Override
public void saveLoginCheckCode(String phone, String checkCode) {
ValueOperations valueOperations = redisTemplate.opsForValue();
// redis键为手机号,值为验证码,过期时间5分钟
valueOperations.set("loginCode:" + phone, checkCode, 300, TimeUnit.SECONDS);
}
   // 保存登录验证码到redis
    @Override
    public void saveLoginCheckCode(String phone, String checkCode) {
        ValueOperations valueOperations = redisTemplate.opsForValue();
        // redis键为手机号,值为验证码,过期时间5分钟
        valueOperations.set("loginCode:" + phone, checkCode, 300, TimeUnit.SECONDS);
    }
// 保存登录验证码到redis @Override public void saveLoginCheckCode(String phone, String checkCode) { ValueOperations valueOperations = redisTemplate.opsForValue(); // redis键为手机号,值为验证码,过期时间5分钟 valueOperations.set("loginCode:" + phone, checkCode, 300, TimeUnit.SECONDS); }

3. 编写发送验证码短信

这个就是第三点的第5小点,不重复赘述。

4. 发送登录短信

@RestController
@RequestMapping("/user")
public class ShoppingUserController {
@Service
private UserService userService;
@Service
private MessageService messageService;
/**
* 发送登录短信验证码
* @param phone 手机号
* @return 操作结果
*/
@GetMapping("/sendLoginCheckCode")
public BaseResult sendLoginCheckCode(String phone) {
// 1.生成随机四位数
String checkCode = RandomUtil.buildCheckCode(4);
// 2.发送短信
BaseResult result = messageService.sendMessage(phone, checkCode);
// 3.发送成功,将验证码保存到redis中,发送失败,返回发送结果
if (200 == result.getCode()) {
userService.saveLoginCheckCode(phone, checkCode);
return BaseResult.ok();
} else {
return result;
}
}
/**
* 手机号验证码登录
* @param phone 手机号
* @param checkCode 验证码
* @return 登录结果
*/
@PostMapping("/loginCheckCode")
public BaseResult loginCheckCode(String phone, String checkCode){
String sign = userService.loginCheckCode(phone, checkCode);
return BaseResult.ok(sign);
}
}
@RestController
@RequestMapping("/user")
public class ShoppingUserController {
    @Service
    private UserService userService;
    @Service
    private MessageService messageService;
        /**
     * 发送登录短信验证码
     * @param phone 手机号
     * @return 操作结果
     */
    @GetMapping("/sendLoginCheckCode")
    public BaseResult sendLoginCheckCode(String phone) {
        // 1.生成随机四位数
        String checkCode = RandomUtil.buildCheckCode(4);
        // 2.发送短信
        BaseResult result = messageService.sendMessage(phone, checkCode);
        // 3.发送成功,将验证码保存到redis中,发送失败,返回发送结果
        if (200 == result.getCode()) {
            userService.saveLoginCheckCode(phone, checkCode);
            return BaseResult.ok();
        } else {
            return result;
        }

    }
    /**
     * 手机号验证码登录
     * @param phone 手机号
     * @param checkCode 验证码
     * @return 登录结果
     */
    @PostMapping("/loginCheckCode")
    public BaseResult loginCheckCode(String phone, String checkCode){
        String sign = userService.loginCheckCode(phone, checkCode);
        return BaseResult.ok(sign);
    }

}
@RestController @RequestMapping("/user") public class ShoppingUserController { @Service private UserService userService; @Service private MessageService messageService; /** * 发送登录短信验证码 * @param phone 手机号 * @return 操作结果 */ @GetMapping("/sendLoginCheckCode") public BaseResult sendLoginCheckCode(String phone) { // 1.生成随机四位数 String checkCode = RandomUtil.buildCheckCode(4); // 2.发送短信 BaseResult result = messageService.sendMessage(phone, checkCode); // 3.发送成功,将验证码保存到redis中,发送失败,返回发送结果 if (200 == result.getCode()) { userService.saveLoginCheckCode(phone, checkCode); return BaseResult.ok(); } else { return result; } } /** * 手机号验证码登录 * @param phone 手机号 * @param checkCode 验证码 * @return 登录结果 */ @PostMapping("/loginCheckCode") public BaseResult loginCheckCode(String phone, String checkCode){ String sign = userService.loginCheckCode(phone, checkCode); return BaseResult.ok(sign); } }

? 最后

到这,一个完整的阿里云发送验证码就结束啦,咱们下期再见!!!

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYmnPC3H' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片