一、在正式编码之前,需要先在腾讯云设置一下短信签名的模板,选择签名类型时,如果是企业选择企业,如果是个人需要选择公众号,如果没有公众号需要申请一个,腾讯云设置签名模板的教程可以参考:https://blog.csdn.net/weixin_45001200/article/details/118878336?spm=1001.2014.3001.5501
二:前端代码实现,效果图如下,账号密码登录和手机号验证码登录调用了element-ui中的Tabs标签页。
重 置
登 录
script标签中内容如下:
data() {
return {
activeName: 'first',//新增
logining: false,
loginForm: {
phone: '',
code: ''
},
fieldRules: {
phone: [
{ required: true, message: '请输入手机号', trigger: 'blur' },
],
code: [
{ required: true, message: '请输入验证码', trigger: 'blur' },
]
},
//新添
show: true,
count: '',
timer: null,
checked: true
};
},
methods: {
pLogin() {
let userInfo = {phone:this.loginForm.phone, code:this.loginForm.code}
console.log(userInfo);
this.$api.login.phoneLogin(JSON.stringify(userInfo)).then((res) => {
console.log(res.data);
if(res.code == 200){
console.log("操作成功!");
sessionStorage.setItem('userInfo', JSON.stringify(res.data)) // 保存用户到本地会话
sessionStorage.setItem('token', res.data.token) // 保存用户到本地会话
this.$router.push('/SelectRole')
}else{
console.log("操作失败!");
this.$message({message: '操作失败, ' + res.msg, type: 'error'})
}
}).catch(function(res) {
alert(res);
});
},
//发送手机验证码
getPhoneCode () {
let userInfo = {phone:this.loginForm.phone}
console.log(userInfo);
this.$api.login.getPhoneCode(JSON.stringify(userInfo)).then((res) => {
if(res.code == 200){
console.log("验证码发送成功!");
}
}).catch(function(res) {
alert(res);
});
// 验证码倒计时
if (!this.timer) {
this.count = TIME_COUNT
this.show = false
this.timer = setInterval(() => {
if (this.count > 0 && this.count <= TIME_COUNT) {
this.count--
} else {
this.show = true
clearInterval(this.timer)
this.timer = null
}
}, 1000)
}
}
}
三:后端代码实现,实现短信登录在后台需要写两个接口,一个发送短信验证码的接口,另一个实现短信验证码登录的接口。
1、引入腾讯云短信服务的依赖
com.github.qcloudsms
qcloudsms
1.0.2
2、实现发送短信验证的接口:入参:手机号,此接口由四步组成,
1)判断手机号是否为空,手机号如果为空则往前台返回错误信息
if(StringUtils.isEmpty("phone")){
return ResultJson.error("手机号不能为空!");
}
2)判断手机号是否符合格式,这里使用了正则表达式进行判断,手机号如果为空则往前台返回错误信息
String regex = "^1[1-9]\\d{9}$";
if (!Pattern.matches(regex, String.valueOf(phone))) {
return ResultJson.error("手机号格式不正确!");
}
3)将验证码存到缓存中并设置有效时间,一般设置为十分钟,这里将验证码放到了redis缓存中,验证码调用random函数随机生成,将生成的验证码以键值对的形式并设置有效时间存到redis缓存中中。
String code = DXMessageUtil.random();
redisUtil.setex("phoneCode",code,60*10);
DXMessageUtil.random()方法;
//随机生成6位短信验证码的函数
public static String random(){
String x= String.valueOf((int)((Math.random()*9+1)* Math.pow(10,6-1)));
return x;
}
redisUtil.setex()方法;
public boolean setex(String key,Object value,long expire){
try{
//TimeUnit.SECONDS指定类型为秒
redisTemplate.opsForValue().set(key,value,expire, TimeUnit.SECONDS);
return true;
}catch (Exception e){
log.error("redis set value and expire exception:{}",e);
return false;
}
}
4)往手机发送短信验证码,这一步使用了腾讯云发送短信固定的类,将从前台传来的手机号以及随机生成的验证码作为参数传到腾讯云发送短信固定的类中。
if(!DXMessageUtil.sendMessage(phone,String.valueOf(redisUtil.get("phoneCode")))){
return ResultJson.error("验证码发送失败!");
}
DXMessageUtil.sendMessage()方法如下,这里。。。对应的位置需要写成腾讯云中对应的内容。appId、appKey、templateId、smsSign在如下位置查找:
appId、appKey在如下位置:
短信正文模板在如下位置:
签名内容在如下位置:
DXMessageUtil.sendMessage()方法如下:
public static Boolean sendMessage(Long phone, String code){
int appId = 。。。。; //appId
String appKey = "。。。"; //appKey
String phoneNumber = String.valueOf(phone);
int templateId = 。。。; // 短信正文模板
String smsSign = "。。。"; //签名内容
//可能获取失败,所以放在try-chach中
try {
String[] params = {code};//传入验证码和时间数组,根据短信模板自行调整
log.info("入参电话:"+phoneNumber);
log.info("入参验证码:"+code);
//创建短信调用接口 传入刚刚的应用id 和 key
SmsSingleSender sender = new SmsSingleSender(appId, appKey);
//调用方法发送短信 传入国家码 电话号码 模板id 模板参数 签名 扩展码为空 返回参数为空
SmsSingleSenderResult result = sender.sendWithParam("86", phoneNumber, templateId,params,smsSign,"","");
} catch(HTTPException e) {
// HTTP响应码错误
log.info("HTTP响应码错误!");
e.printStackTrace();
return false;
} catch(JSONException e) {
// json解析错误
log.info("json解析错误!");
e.printStackTrace();
return false;
} catch(IOException e) {
// 网络IO错误
log.info("网络IO错误!");
e.printStackTrace();
return false;
}
return true;
}
3、实现短信验证码登录的接口:入参:手机号,验证码,此接口由四步组成:
1)判断手机号是否为空,如上
2)判断手机号格式是否正确,如上
3)判断距离上次发送该类型的验证码是否失效
if((String.valueOf(redisUtil.get("phoneCode")))==null){
return ResultJson.error("验证码已失效!");
}
4)判断用户是否存在,若用户存在则将入参验证码和redis缓存中的验证码进行比较以及判断数据库中是否存在该手机号的用户,如果都验证正确则登录成功。