SpringBoot integrates Tencent Cloud SMS service

foreword

It can be said that now a mature software will basically have the scenario of sending SMS verification code; for example, in these scenarios:

  1. User registers with mobile phone number
  2. User logs in with SMS verification code
  3. If the user forgets the password, reset the password by sending the mobile phone verification code
  4. Modify mobile number
  5. change Password

In the above scenarios, we need to integrate SMS services. Now there are many SMS services, such as: Tencent Cloud, Alibaba Cloud, etc.
In this article, SpringBoot will be used to integrate Tencent Cloud's SMS service.

start integration

Preparation Phase

We need to register a Tencent Cloud account first, and then find SMS in Tencent Cloud's products. insert image description here
There are corresponding SMS packages to choose from. If you are a new user, there will be a certain number of free SMS messages.
Then we enter the SMS console page, we first need to create a SMS signature , in which the signature purpose, signature type and signature content are filled in according to your actual situation.
Note: The content of the signature is the content in the square brackets of the SMS verification code [], such as: [xxx] 1234 is your verification code, please enter it within 5 minutes. Its signature content is xxx. insert image description here
After filling in, click OK. In the signature management, you can see the SMS signature just created. The signature is ready to use when the displayed status changes to Approved .
insert image description here
Next we need to create the template for the SMS. Select the option to create a text template and fill it in according to the actual situation. Fill in and confirm. Among them, the variable parameters such as {1}{2} in the SMS content part are dynamic parameters, which need to be carried when we request Tencent Cloud SMS service in the code.
insert image description here
The status of the created template shows that it has passed and can be used.
insert image description here

Coding stage

pom file

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.junwei</groupId>
    <artifactId>smsdemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>smsdemo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <qcloudsms.version>1.0.6</qcloudsms.version>
        <lombok.versino>1.18.8</lombok.versino>
        <httpclient.version>4.5.9</httpclient.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.qcloudsms</groupId>
            <artifactId>qcloudsms</artifactId>
            <version>${qcloudsms.version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.versino}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>${httpclient.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

application.yml

Note: Redis cache database is required

server:
  port: 9016

spring:
  application:
    name: sms-service

  redis:
    host: 127.0.0.1
    port: 6379

smsconfig:
  appId: 腾讯云短信应用id
  appkey: 腾讯云短信应用key
  smsSign: 腾讯云创建的短信签名
  templateid: 腾讯云短信模板id
  invalidtime: 验证码失效时间
  # redis存储前缀,根据不同类型做区分
  phone-prefix: LOGIN,REGIST,FORGET_PASSWORD,UPDATE_MOBILE,UPDATE_PASSWORD,WX_UN_TYING,UPDATE_NEW_MOBILE

logging:
  level:
    root: info

The SMS signature and SMS template id can be seen after the above configuration is successful; Tencent Cloud AppId and AppKey are here:
insert image description here

Controller

@RestController
@RequestMapping("sms")
public class SmsController {
    
    

    @Autowired
    private SmsService smsService;

    @PostMapping("send")
    public Result send(@RequestBody SendSmsDto sendSmsDto) {
    
    
        smsService.sendSmsCode(sendSmsDto);
        return Result.success("");
    }

    @PostMapping("verify")
    public Result verify(@RequestBody VerifyCodeDto verifyCodeDto) {
    
    
        smsService.verifyCode(verifyCodeDto);
        return Result.success("");
    }

}

SmsConfig

@Configuration
public class SmsConfig {
    
    
    /**
     * 初始化主账号名称
     **/
    @Value("${smsconfig.appkey}")
    private String APP_KEY;

    /**
     * 初始化应用ID
     **/
    @Value("${smsconfig.appId}")
    private int APP_ID;

    @Bean
    public SmsSingleSender ssender() {
    
    
        return new SmsSingleSender(APP_ID, APP_KEY);
    }
}

ServiceImpl

@Service
@Slf4j
public class SmsServiceImpl implements SmsService {
    
    

    @Autowired
    private SmsSingleSender smsSingleSender;

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 短信模板ID
     **/
    @Value("${smsconfig.templateid}")
    private int TEMPLATE_ID;
    /**
     * 短信签名内容
     */
    @Value("${smsconfig.smsSign}")
    private String SMS_SIGN;

    @Value("${smsconfig.invalidtime}")
    private String INVALID_TIME;

    @Value("${smsconfig.phone-prefix}")
    private String PHONE_PREFIX;

    @Override
    public void sendSmsCode(SendSmsDto sendSmsDto) {
    
    
        // 可以在发送验证码之前对当前手机号做一些验证,如该手机号是否注册过
        // 为了防止短信轰炸可以根据业务需求在此做一些限制
        String code = SmsUtil.getCode();
        try {
    
    
            ArrayList<String> params = new ArrayList<>();
            params.add(code);
            params.add(INVALID_TIME);
            SmsSingleSenderResult senderResult = smsSingleSender
                    .sendWithParam("86", sendSmsDto.getMobile(),
                            TEMPLATE_ID, params, SMS_SIGN, "", "");
            int statusCode = senderResult.result;
            String statusMsg = senderResult.errMsg;
            log.info("发送短信,腾讯云返回状态码:" + statusCode);
            log.info("发送短信,腾讯云返回信息:" + statusMsg);
            // 过于频繁
            if (Constants.SEND_SMS_CODE_FREQUENT == statusCode) {
    
    
                throw new SmsException(R.USER_LOGIN_ERROR3, "");
            }
            // 达到上限
            if (Constants.SEND_SMS_CODE_UPPER == statusCode) {
    
    
                throw new SmsException(R.USER_CODE_TOOMANY, "");
            }
            if (Constants.SEND_SMS_CODE_SUCCESS != statusCode) {
    
    
                throw new SmsException(R.sms_send_error, "");
            }
            if (!redisUtil.setCacheObject(SmsUtil.map.get(sendSmsDto.getType()) + sendSmsDto.getMobile(),
                    code, 60 * Integer.parseInt(INVALID_TIME))) {
    
    
                throw new SmsException(R.sms_send_error, "");
            }
        } catch (Exception e) {
    
    
            throw new SmsException(R.sms_send_error, "");
        }
    }

    @Override
    public void verifyCode(VerifyCodeDto verifyCodeDto) {
    
    
        String redisCode = (String) redisUtil.getCacheObject(SmsUtil.map
                .get(verifyCodeDto.getType()) + verifyCodeDto.getMobile());
        AssertUtil.isNull(redisCode, R.USER_LOGIN_ERROR4);
        if (redisCode.equals(verifyCodeDto.getCode())) {
    
    
            redisUtil.delete(SmsUtil.map.get(verifyCodeDto.getType()) + verifyCodeDto.getMobile());
        } else {
    
    
            throw new SmsException(R.USER_CODE_ERROR, "");
        }
    }
}

Only the key part of the code is shown in the article. If you need detailed code, please clone the warehouse: SpringBoot integrates Tencent Cloud SMS service

functional testing phase

Here, Postman is used to test the interface.
The first thing to test is the SMS verification code sending interface:
according to the interface and parameter settings, the post request method is used here, and two parameters, the mobile phone number and the SMS verification code type, need to be passed in. The test request was successful.
insert image description here
The sending is successful, and the mobile phone receives the verification code:
insert image description here

Next, we test the verification verification code interface:
According to the interface and parameter settings, the post request method is used here, and three parameters need to be passed in: the mobile phone number, the received SMS verification code, and the type of SMS verification code, and the verification is successful.
insert image description here
So far, the SMS service has been integrated, and you can do some corresponding processing according to your business needs before or after sending the SMS.
Finally, the git address of the detailed code is provided:https://gitee.com/junweiw/tx_send_sms.git

Guess you like

Origin blog.csdn.net/wFitting/article/details/106242142