登录中的获取验证码
你知道在点击“获取” 两字之后会发生什么吗?
没错,就是去发送验证码,哈哈哈哈哈哈哈哈。
还有一步,就是在redis中要存储验证码,并设置时间,判断验证码是否过期,
我就当都知道redis,下面记录一下:发送短信&redis存储验证码的过程。
前端
用到了vue框架,仅展示部分代码,完整代码在末尾处。
HTML
<!-- 手机号注册 -->
<div class="am-tab-panel" id="phoneRegisterDiv">
<form method="post">
<div class="user-phone">
<label for="phone"><i class="am-icon-mobile-phone am-icon-md"></i></label>
<input type="tel" name="" v-model="phoneUserForm.phone" id="phone" placeholder="请输入手机号">
</div>
<div class="verification">
<label for="code"><i class="am-icon-code-fork"></i></label>
<input type="tel" name="" v-model="phoneUserForm.verifyCode" id="code" placeholder="请输入验证码">
<!--button 默认是 submit 提交-->
<button type="button" @click="sendMobileCode">获取</button>
</div>
<div class="user-pass">
<label for="password"><i class="am-icon-lock"></i></label>
<input type="password" name="" v-model="phoneUserForm.password" id="password" placeholder="设置密码">
</div>
<div class="user-pass">
<label for="passwordRepeat"><i class="am-icon-lock"></i></label>
<input type="password" name="" v-model="phoneUserForm.confirmPassword" id="passwordRepeat" placeholder="确认密码">
</div>
</form>
<div class="login-links">
<label for="reader-me">
<input id="reader-me" type="checkbox"> 点击表示您同意商城《服务协议》
</label>
</div>
<div class="am-cf">
<input type="submit" name="" value="注册" class="am-btn am-btn-primary am-btn-sm am-fl">
</div>
<hr>
</div>
js
<script type="text/javascript">
new Vue({
el: "#phoneRegisterDiv",
data:{
phoneUserForm:{
// 先给默认值
phone: "1570492960",
verifyCode:"",
password: "1",
confirmPassword: "1"
}
},
methods:{
/* 发送短信获取验证码*/
sendMobileCode() {
//1.判断手机号不为空
if (!this.phoneUserForm.phone) {
alert("手机号不能为空");
return;
}
//2.获取按钮,禁用按钮 发送时灰化不能使用,发送成功倒计时60才能使用,如果发送失败立即可以发送
var sendBtn = $(event.target);
sendBtn.attr("disabled", true);
this.$http.post('/verifyCode/sms/register?phone=' + this.phoneUserForm.phone).then((res) => {
console.log(res);
var ajaxResult = res.data;
if (ajaxResult.success) {
alert("手机验证码已经发送到您的手机,请在5分钟内使用");
//3.1.发送成:倒计时
var time = 60;
var interval = window.setInterval(function () {
//每一条倒计时减一
time = time - 1;
//把倒计时时间搞到按钮上
sendBtn.html(time);
//3.2.倒计时完成恢复按钮
if (time <= 0) {
sendBtn.html("重发");
sendBtn.attr("disabled", false);
//清除定时器
window.clearInterval(interval);
}
}, 1000);
} else {
//3.3.发送失败:提示,恢复按钮
sendBtn.attr("disabled", false);
alert("发送失败:" + ajaxResult.message);
}
});
}
}
})
</script>
后端
这里用的是springboot 与redis集成后的springboot springdata redis
1)pom.xml 导入jar
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2)application.yaml 做配置
spring:
redis:
database: 0
host: 127.0.0.1
port: 6379
password: 123456
jedis:
pool:
max-wait: 2000ms
min-idle: 2
max-idle: 8
3)代码
controller.java
import cn.zhistudy.basic.util.AjaxResult;
import cn.zhistudy.user.service.IVerifyCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 获取验证码
*/
@RestController
@RequestMapping("/verifyCode")
public class VerifyCodeController {
@Autowired
private IVerifyCodeService verifyCodeService;
@PostMapping("/sms/register")
public AjaxResult getVerifyCodeForSms(@RequestParam(required = true, value = "phone") String phone){
try {
return verifyCodeService.getVerifyCodeForSendSms(phone);
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.me().setMessage("短信发送失败,请重新发送!");
}
}
}
seviceImpl.java
这里运用到redis 存储验证码。
import cn.zhistudy.basic.util.AjaxResult;
import cn.zhistudy.basic.util.StrUtils;
import cn.zhistudy.user.domain.User;
import cn.zhistudy.user.mapper.UserMapper;
import cn.zhistudy.user.service.IVerifyCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.util.concurrent.TimeUnit;
@Service
@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
public class VerifyCodeServiceImpl implements IVerifyCodeService {
@Autowired
private UserMapper userMapper;
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Override
public AjaxResult getVerifyCodeForSendSms(String phone) {
// 1、检验
// 1.1 检测手机号是否为空
if (StringUtils.isEmpty(phone)){
return AjaxResult.me().setMessage("手机好不能为空");
}
// 1.2 验证手机号是否已经注册
User user = userMapper.loadByPhone(phone);
if (user!=null)
return AjaxResult.me().setMessage("此手机号已经注册!");
// 2、验证原来的验证码是否有效
String key = "register_" + phone;
String codeStr = redisTemplate.opsForValue().get(key); // 获取验证码
String code = ""; // 验证码
// 2.1 验证码过期
if (StringUtils.isEmpty(codeStr)){
// 2.2.1 重新生成新的4位验证码
code = StrUtils.getComplexRandomString(4);
} else{
// 2.2 验证码有效
// 2.2.1 ,没有过重发的时间,报错(非法)
code = codeStr.split(":")[0];
String timeStr = codeStr.split(":")[1];
if (System.currentTimeMillis() - Long.parseLong(timeStr) < 1000*60){
return AjaxResult.me().setMessage("非法重复发送验证码!");
}
}
// 3 将新的验证码存入redis中
redisTemplate.opsForValue().set(key, code+":"+System.currentTimeMillis(), 3, TimeUnit.MINUTES);
// 4 将新的验证码发送给注册用户
SmsUtil.sendMsg(phone,"你的验证码为:"+code+",请在3分钟内使用!");
System.out.println("验证码为:"+code);
return AjaxResult.me();
}
}
这里的SmsUtil是发送短信验证码的工具类,根据自己发送短信的平台自己封装工具类。我这里用的是中国网建,也可以用想阿里云、腾讯云短信。。。
完整项目在:点击查看项目
(完!!!)