要求
- 给手机发送6位验证码,有效时间120s
- 接收到之后输入验证码反馈验证码成功或者失败
- 每天只能发送三次
实现
思路:
1.先写出前端页面,输入手机号,发送验证码按钮
2.点击发送验证码,后台生成6位随机数,将这6位随机数放到redis中,设置有效时间120s
3.前台输入验证码,后台验证从redis取出来验证码和前台传过来的数据进行比对,反馈正确或者错误
4.加一个计数器,加一个唯一标识,加个锁,当验证码发送三次后锁设置为lock,一天有效
5.当锁为lock的时候,说明已发送三次验证,锁定一天,给前端响应
具体代码
导入依赖:
<!--随机数-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!--redis-->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
配置文件:
# Redis服务器地址
spring.redis.host=服务器ip
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
# Redis服务器超时时间(毫秒)
spring.redis.timeout=5000
# 连接池最大连接数(使用负值表示没有限制) 默认 8
spring.redis.lettuce.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)默认-1
spring.redis.lettuce.pool.max-wait=-1
# 连接池中的最大空闲连接 默认 8
spring.redis.lettuce.pool.max-idle=8
# 连接池中的最小空闲连接 默认 0
spring.redis.lettuce.pool.min-idle=0
前端:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>手机验证码</title>
<script type="text/javascript" th:src="@{/js/jquery.js}" src="../static/js/jquery.js"></script>
</head>
<body>
<style type="text/css">
.msgs{display:inline-block;width:104px;color:#fff;font-size:12px;border:1px solid #0697DA;text-align:center;height:30px;line-height:30px;background:#0697DA;cursor:pointer;}
form .msgs1{background:#E6E6E6;color:#818080;border:1px solid #CCCCCC;}
</style>
<div>
手机号:<input type="text" id="phoneNumber" name="phoneNumber" style="height: 25px"/>
<span id="getcode" class="msgs">获取短信验证码</span>
<span id="span">Cyw</span>
<span style="visibility: visible"></span>
</div><br/><br/>
<div>
请输入验证码:<input type="text" name="code" id="code">
<button id="btn" style="background-color: aqua">确认</button>
<span id="span1">Cyw1</span>
</div>
<script type="text/javascript">
$(function () {
//获取短信验证码
var validCode=true;
$(".msgs").click (function () {
var phoneNumber = $("#phoneNumber").val();
var span = $("#span");
if (phoneNumber == ""){
var msg = "请输入手机号"
span.css("color","red");
span.html(msg);
return false;
}
if (phoneNumber.length != 11){
var msg = "手机号11位"
span.css("color","red");
span.html(msg);
return false;
}
var msg = "正在发送,请稍后"
span.css("color","blue");
span.html(msg);
$.post("/redis/sendCode",{phoneNumber:phoneNumber},function (data) {
var span = $("#span");
if(data.toString()==phoneNumber){
var msg = "发送成功"
span.css("color","green");
span.html(msg);
}
if (data.toString()=="overThree"){
var msg = "每天只能验证3次"
span.css("color","red");
span.html(msg);
return false;
}
});
var time=120;
var code=$(this);
if (validCode) {
validCode=false;
code.addClass("msgs1");
var t=setInterval(function () {
time--;
code.html(time+"秒");
if (time==0) {
clearInterval(t);
code.html("重新获取");
validCode=true;
code.removeClass("msgs1");
}
},1000)
}
})
$("#btn").click(function () {
var code = $("#code").val();
var phoneNumber = $("#phoneNumber").val();
var span1 = $("#span1");
if (code == ""){
var msg = "请输入验证码"
span1.css("color","red");
span1.html(msg);
return false;
}
$.post("/redis/checkCode",{code:code,phoneNumber:phoneNumber},function (data) {
if(data.toString()=="checkOK"){
var msg = "验证成功"
span1.css("color","green");
span1.html(msg);
}
if (data.toString()=="checkFail"){
var msg = "验证码输入错误"
span1.css("color","red");
span1.html(msg);
}
});
});
})
</script>
</body>
</html>
后台:
package com.mcy.redisdemo.controller;
import com.mcy.redisdemo.util.RedisUtil;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;
/**
* @Author: CYW
* @Date: 2021/1/17 00:02
*/
@RestController
@RequestMapping("/redis")
public class RedisController {
@Autowired
private RedisUtil redisUtil;
@Autowired
private StringRedisTemplate stringRedisTemplate;
/**
* 定义一个手机号发验证码的次数count_和一个锁lock_
* _后面放手机号作为唯一标识
* 每请求一次,+1使用redis实现
* 当count>3时,把锁设为 1,锁的有效时间为 1 天,再次请求返回fail
*/
//发送次数,下划线后面是手机号作为唯一标识
private String COUNT = "count_";
//是否被锁
private String LOCK = "lock_";
/**
* @Author: CYW
* 获取验证码
* @return
*/
@PostMapping("/sendCode")
public String sendCode(String phoneNumber){
ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
// 生成6位随机数(验证码)
String random = RandomStringUtils.randomNumeric(6);
System.out.println(random);
//把验证码存入redis中,有效时间两分钟(120秒)
redisUtil.set(phoneNumber+"code",random,120);
//每访问一次,次数 +1,如果 >3 次 则返回给用户信息
redisUtil.incr(COUNT+phoneNumber,1);
System.out.println("发送次数为:"+opsForValue.get(COUNT + phoneNumber));
if (Integer.parseInt(opsForValue.get(COUNT+phoneNumber))>2){
if ("lock".equals(redisUtil.get(LOCK+phoneNumber))) {
return "overThree";
}
}
if (Integer.parseInt(opsForValue.get(COUNT+phoneNumber))>2){
//锁一天手机号不让再次获取验证码
redisUtil.set(LOCK+phoneNumber,"lock",24*60);
}
return phoneNumber;
}
/**
* @Author: CYW
* 获取验证码
* @return
*/
@PostMapping("/checkCode")
public String checkCode(String code,String phoneNumber){
System.out.println(code);
System.out.println("手机号"+phoneNumber);
System.out.println(redisUtil.get(phoneNumber+"code"));
System.out.println(code.equals(redisUtil.get(phoneNumber+"code")));
if (code.equals(redisUtil.get(phoneNumber+"code"))){
//验证成功
return "checkOK";
}
return "checkFail";
}
}
大功告成