java代码调用腾讯云实现短信登录功能

发布于:2023-01-31 ⋅ 阅读:(565) ⋅ 点赞:(0)

前言:
视频里老师用的是阿里云,那由于阿里云要收费并且申请个人短信服务里的没有证明文件好像申请不了。身为多年白嫖党的我决定另辟蹊径,于是冲了冲浪,发现腾讯云有送100条免费(阿里云也有),tencent主要是可以通过申请个人公众号去申请签名,而不用七七八八证明。

下面是让人劝退的签名管理
在这里插入图片描述
下面是新用户开通都有赠送
在这里插入图片描述
好了,接下来进入正题注册腾讯云并开通短信服务首先你要有一个👉微信公众号注册
注册比较简单就这里就不说了 我这里选的是订阅号
然后注册并登录腾讯云
在这里插入图片描述
首先就是申请一个签名
在这里插入图片描述
下图是公众号后台截图
在这里插入图片描述
在这里插入图片描述
接下来就是申请模板
在这里插入图片描述
在这里插入图片描述
创建accesskey也可以说获取 “secretId” 和 “secretKey”
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
接下来我们试试在线调用是否可以跑通
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
SmsSdkAppId
在这里插入图片描述
TemplateId
申请成功的模板id
在这里插入图片描述
在这里插入图片描述
接下来是我的

在这里插入图片描述
ok调用成功
在这里插入图片描述
在这里插入图片描述

接下来进入正题放到项目里

首先准备几个工具类
生成验证码

package com.ghc.reggie.tencentSMSUtils; //这里记得导自己的包
import java.text.DecimalFormat;
import java.util.Random;
public class RamdomUtils {

    private static final Random random = new Random();
    //我定义的验证码位数是6位
    private static final DecimalFormat sixdf = new DecimalFormat("000000");

    public static String getSixBitRandom() {
        return sixdf.format(random.nextInt(1000000));
    }
}

封装连接参数,以及调用tencentCloud的属性

package com.ghc.reggie.tencentSMSUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
包路径自己更改一下
//实现了InitializingBean接口,当spring进行初始化bean时,会执行afterPropertiesSet方法
@Component
@PropertySource("classpath:application.yml")
@ConfigurationProperties(prefix = "tencent.msm")
public class MsmConstantUtils implements InitializingBean {

    @Value("${id}")
    private String secretID ;

    @Value("${secret}")
    private String secretKey ;

    @Value("${endPoint}")
    private String endPoint;

    @Value("${appId}")
    private String appId;

//    @Value("${signName}")
//    private String signName;

    @Value("${templateId}")
    private String templateId;
    //六个相关的参数
    public static String SECRET_ID;
    public static String SECRET_KEY;
    public static String END_POINT;
    public static String APP_ID;
//    public static String SIGN_NAME;
    public static String TEMPLATE_ID;

    @Override
    public void afterPropertiesSet() throws Exception {
        SECRET_ID = secretID;
        SECRET_KEY = secretKey;
        END_POINT = endPoint;
        APP_ID = appId;
//        SIGN_NAME = signName;
        TEMPLATE_ID = templateId;
    }
}

yml配置文件
tencent:
      msm:
      id: secretId     换上自己的id和key
      secret: secretkey
      endPoint: sms.tencentcloudapi.com
      appId: SmsSdkAppId
      signName: 公众号名
      templateId: 模板id

然后把这些属性封装到一个工具类,并将属性注入spring容器中

package com.ghc.reggie.tencentSMSUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@Component
@PropertySource("classpath:application.yml")
@ConfigurationProperties(prefix = "tencent.msm")
public class MsmConstantUtils implements InitializingBean {

    @Value("${id}")
    private String secretID ;

    @Value("${secret}")
    private String secretKey ;

    @Value("${endPoint}")
    private String endPoint;

    @Value("${appId}")
    private String appId;

    @Value("${signName}")
    private String signName;

    @Value("${templateId}")
    private String templateId;
    //六个相关的参数
    public static String SECRET_ID;
    public static String SECRET_KEY;
    public static String END_POINT;
    public static String APP_ID;
    public static String SIGN_NAME;
    public static String TEMPLATE_ID;

    @Override
    public void afterPropertiesSet() throws Exception {
        SECRET_ID = secretID;
        SECRET_KEY = secretKey;
        END_POINT = endPoint;
        APP_ID = appId;
        SIGN_NAME = signName;
        TEMPLATE_ID = templateId;
    }
}

接下来是实现类,写发送短信的具体逻辑

@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService{
    @Override
    public boolean send(String phone,String code) {
        try {
            //这里是实例化一个Credential,也就是认证对象,参数是密钥对;你要使用肯定要进行认证
            Credential credential = new Credential(MsmConstantUtils.SECRET_ID, MsmConstantUtils.SECRET_KEY);

            //HttpProfile这是http的配置文件操作,比如设置请求类型(post,get)或者设置超时时间了、还有指定域名了
            //最简单的就是实例化该对象即可,它的构造方法已经帮我们设置了一些默认的值
            HttpProfile httpProfile = new HttpProfile();
           
            httpProfile.setEndpoint(MsmConstantUtils.END_POINT);

            //实例化一个客户端配置对象,这个配置可以进行签名(使用私钥进行加密的过程),对方可以利用公钥进行解密
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);

            //实例化要请求产品(以sms为例)的client对象
            SmsClient smsClient = new SmsClient(credential, "ap-nanjing", clientProfile);

            //实例化request封装请求信息
            SendSmsRequest request = new SendSmsRequest();
            String[] phoneNumber = {phone};
            request.setPhoneNumberSet(phoneNumber);     //设置手机号
            request.setSmsSdkAppid(MsmConstantUtils.APP_ID);
            request.setSign(MsmConstantUtils.SIGN_NAME);
            
            request.setTemplateID(MsmConstantUtils.TEMPLATE_ID);
            //生成随机验证码,我的模板内容的参数只有一个
            String[] templateParamSet = {code};
            request.setTemplateParamSet(templateParamSet);

            //发送短信
            SendSmsResponse response = smsClient.SendSms(request);
            log.info(SendSmsResponse.toJsonString(response));
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}

控制器controller

@RestController
@ResponseBody
@RequestMapping("/user")
@Slf4j
public class UserController {
@PostMapping("/sendMsg")
    public R<String> send(@RequestBody User user, HttpSession Session) {
        //获取手机号
        String phone=user.getPhone();

        //生成随机的六位验证码
        if (StringUtils.isNotEmpty(phone)){
            String code = RamdomUtils.getSixBitRandom().toString();
            log.info("验证码 code{}",code);

            //调用腾讯云的API实现发送短信
            boolean result = userService.send(phone,code);

            if (result){
                //将生成的验证码保存导Session中
                Session.setAttribute(phone,code);
                return R.success("短信发送成功");
            }
            }
        return R.error("短信发送失败");
    }
    }

ok完成了,去前端调用试试

debug模式,在UserServiceImpl的send方法里打个断点
![在这里插入图片描述](https://img-blog.csdnimg.cn/c5383f276b4e4ddcb3
接下来点击获取跳进断点
第一次没仔细看,看了大概最后跳到true就直接放过了,结果等了好一会验证码还没过来,发现不对了。于是细看了一次里面的参数,发现!!!
在这里插入图片描述
传入的参数签名内容乱码了,因为yml文件编码格式我已经设成utf-8了,所以配置文件没有乱码,但是最为请求参数传入调用第三方时乱码了。后来想了想,这本身申请的签名内容就是个定值,索性在send方法里直接写死,不通过spring注入。
在这里插入图片描述
又跑了一遍,好了~~~~又不行。裂开!,这里卡了好久确实找不出哪不对了。
后来回看了在线调用的代码,粘到了文本上反复比对
在这里插入图片描述
发现api版本不一样
在这里插入图片描述
重点是参数名不一样

在这里插入图片描述
把上图3个api换成21版本
在这里插入图片描述
回到页面重新调用下,发现 成了!


网站公告

今日签到

点亮在社区的每一天
去签到