验证码案例
一 思路
①:随机生成验证码(4位);
②:设置验证码的存活时间;
③:区分验证码;
简单来说:
一般来说,验证码的长度就设置为4位即可,设置验证码的有效时间为5分钟;
如果t是在一分钟以内,提示用户不能重复获取验证码;
如果t是大于一分钟,小于五分钟,可以重复获取验证码,但是默认使用第一次发送的验证码;
如果t是大于了五分钟,再重新发送新的验证码;
注意:
需要设置生成验证码时的生成时间;
t=当前时间-生成验证码的时间
二 代码
AjaxResult工具
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AjaxResult {
private Boolean success=true;
private String msg;
//后端向前台响应的数据
private Object resultObj;
public AjaxResult(Boolean success,String msg){
this.success=success;
this.msg=msg;
}
public AjaxResult setResultObj(Object resultObj){
this.resultObj=resultObj;
return this;
}
}
1 生成代码工具
package cn.itsource.pethome.basic.util;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class StrUtils {
/**
* 把逗号分隔的字符串转换字符串数组
*
* @param str
* @return
*/
public static String[] splitStr2StrArr(String str,String split) {
if (str != null && !str.equals("")) {
return str.split(split);
}
return null;
}
/**
* 把逗号分隔字符串转换List的Long
*
* @param str
* @return
*/
public static List<Long> splitStr2LongArr(String str) {
String[] strings = splitStr2StrArr(str,",");
if (strings == null) return null;
List<Long> result = new ArrayList<>();
for (String string : strings) {
result.add(Long.parseLong(string));
}
return result;
}
/**
* 把逗号分隔字符串转换List的Long
*
* @param str
* @return
*/
public static List<Long> splitStr2LongArr(String str,String split) {
String[] strings = splitStr2StrArr(str,split);
if (strings == null) return null;
List<Long> result = new ArrayList<>();
for (String string : strings) {
result.add(Long.parseLong(string));
}
return result;
}
public static String getRandomString(int length) {
String str = "0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < length; i++) {
int number = random.nextInt(10);
sb.append(str.charAt(number));
}
return sb.toString();
}
public static String getComplexRandomString(int length) {
String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < length; i++) {
int number = random.nextInt(62);
sb.append(str.charAt(number));
}
return sb.toString();
}
public static String convertPropertiesToHtml(String properties){
//1:容量:6:32GB_4:样式:12:塑料壳
StringBuilder sBuilder = new StringBuilder();
String[] propArr = properties.split("_");
for (String props : propArr) {
String[] valueArr = props.split(":");
sBuilder.append(valueArr[1]).append(":").append(valueArr[3]).append("<br>");
}
return sBuilder.toString();
}
}
2 验证码代码
①:验证码接口
import cn.itsource.pethome.basic.service.ISendRegisterMobileCodeService;
import cn.itsource.pethome.basic.util.AjaxResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
@RequestMapping("/verification")
public class sendRegisterMobileCodeCtroller {
@Autowired
ISendRegisterMobileCodeService sendRegisterMobileCodeService;
@PostMapping("/sendRegisterMobileCode")
public AjaxResult sendRegisterMobileCode(@RequestBody Map<String,String>param){
try {
//获取前台传递过来的电话号码
String phone = param.get("phone");
//根据电话号码发送验证码
sendRegisterMobileCodeService.sendRegisterMobileCode(phone);
//返回成功信息
return new AjaxResult();
} catch (Exception e) {
e.printStackTrace();
return new AjaxResult(false,e.getMessage());
}
}
}
②:service
public interface ISendRegisterMobileCodeService {
//发送短信验证码
void sendRegisterMobileCode(String phone);
}
③:service实现类
@Service
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
public class SendRegisterMobileCodeServiceImpl implements ISendRegisterMobileCodeService {
@Autowired
private RedisTemplate redisTemplate;
@Override
public void sendRegisterMobileCode(String phone) {
//随机产生4位验证码 JK82
String code = StrUtils.getComplexRandomString(4);
//手机号码获取redis中的验证码 JK82:21312433542423
String codeValue = (String) redisTemplate.opsForValue().get(PetHomeConstant.REGISTER_VERIFICATION_CODE + ":" + phone);
//进行判断验证码的存活时间
if (!StringUtils.isEmpty(codeValue)){
//获取第一次发送的时间
Long firstSendTime = Long.valueOf(codeValue.split(":")[1]);
//判断当前验证码的存活时间段
if (System.currentTimeMillis()-firstSendTime<60*1000){//60秒以内
throw new RuntimeException("亲!一分钟以内不能重复获取验证码哦!!!");
}
//5分钟以内 一分过后 不会报异常 还是使用第一次发送的验证码
code = codeValue.split(":")[0];
}
//2.把验证码存储到redis中,并且有效期是5分钟
redisTemplate.opsForValue().set(PetHomeConstant.REGISTER_VERIFICATION_CODE+":"+phone,
code+":"+System.currentTimeMillis(),5, TimeUnit.MINUTES);
String content = "尊敬的用户,你的验证码为:"+code+",请在5分钟以内完成验证操作!!";
System.out.println(content);
}
public static void main(String[] args) {
String str = "wasd";
System.out.println(StringUtils.isEmpty(str));
}
}
④:前台页面代码
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>注册</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="format-detection" content="telephone=no">
<meta name="renderer" content="webkit">
<meta http-equiv="Cache-Control" content="no-siteapp" />
<link rel="stylesheet" href="../AmazeUI-2.4.2/assets/css/amazeui.min.css" />
<link href="../css/dlstyle.css" rel="stylesheet" type="text/css">
<script src="../AmazeUI-2.4.2/assets/js/jquery.min.js"></script>
<script src="../AmazeUI-2.4.2/assets/js/amazeui.min.js"></script>
<script type="text/javascript" src="./plugins/vue/dist/vue.min.js"></script>
<script type="text/javascript" src="./plugins/axios/dist/axios.min.js"></script>
<!--引入公共的js-->
<script type="text/javascript" src="./js/common.js"></script>
</head>
<body>
<div class="login-boxtitle">
<a href="home/demo.html"><img alt="" src="../images/logobig.png" /></a>
</div>
<div class="res-banner">
<div class="res-main">
<div class="login-banner-bg"><span></span><img src="../images/big.jpg" /></div>
<div class="login-box" id="app">
<div class="am-tabs" id="doc-my-tabs">
<ul class="am-tabs-nav am-nav am-nav-tabs am-nav-justify">
<li class="am-active"><a href="">邮箱注册</a></li>
<li><a href="">手机号注册</a></li>
</ul>
<div class="am-tabs-bd">
<div class="am-tab-panel am-active">
<form method="post">
<div class="user-email">
<label for="email"><i class="am-icon-envelope-o"></i></label>
<input type="email" name="" id="email" placeholder="请输入邮箱账号">
</div>
<div class="user-pass">
<label for="password"><i class="am-icon-lock"></i></label>
<input type="password" name="" id="password" placeholder="设置密码">
</div>
<div class="user-pass">
<label for="passwordRepeat"><i class="am-icon-lock"></i></label>
<input type="password" name="" 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>
</div>
<div class="am-tab-panel">
<h1 style="color: red" v-html="errorMsg"></h1>
<form method="post">
<div class="user-phone">
<label for="phone"><i class="am-icon-mobile-phone am-icon-md"></i></label>
<input type="tel" @blur="checkPhone" v-model="user.phone" name="" id="phone" placeholder="请输入手机号">
</div>
<div class="verification">
<label for="code"><i class="am-icon-code-fork"></i></label>
<input type="tel" name="" v-model="user.code" id="code" placeholder="请输入验证码">
<!--button按钮在form表单内部,默认提交是submit提交-->
<button class="btn" v-html="htmlValue" type="button" :disabled="disabled" href="javascript:void(0);" @click="sendMobileCode" id="sendMobileCode">
获取
</button>
</div>
<div class="user-pass">
<label for="password"><i class="am-icon-lock"></i></label>
<input type="password" name="" id="password" placeholder="设置密码">
</div>
<div class="user-pass">
<label for="passwordRepeat"><i class="am-icon-lock"></i></label>
<input type="password" name="" 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>
<script>
$(function() {
$('#doc-my-tabs').tabs();
})
</script>
</div>
</div>
</div>
</div>
<div class="footer ">
<div class="footer-hd ">
<p>
<a href="# ">恒望科技</a>
<b>|</b>
<a href="# ">商城首页</a>
<b>|</b>
<a href="# ">支付宝</a>
<b>|</b>
<a href="# ">物流</a>
</p>
</div>
<div class="footer-bd ">
<p>
<a href="# ">关于恒望</a>
<a href="# ">合作伙伴</a>
<a href="# ">联系我们</a>
<a href="# ">网站地图</a>
<em>© 2015-2025 Hengwang.com 版权所有. 更多模板 <a href="http://www.cssmoban.com/" target="_blank" title="模板之家">模板之家</a> - Collect from <a href="http://www.cssmoban.com/" title="网页模板" target="_blank">网页模板</a></em>
</p>
</div>
</div>
</div>
</body>
<script>
new Vue({
el: "#app",
data: {
user: {
phone: "",
code: ""
},
//初始化不禁用按钮
disabled: false,
htmlValue: "获取",
//错误提示
errorMsg:""
},
methods: {
//发送手机验证码
sendMobileCode() {
if (!this.user.phone) {
alert("手机号码必填!!");
return;
}
//禁用按钮
this.disabled = true;
//设置初始值
this.htmlValue = 10;
//把vue的this赋值给一个变量方便取值
let that = this;
//开启定时器
let intervalId = setInterval(function () {
that.htmlValue--;
if(!that.htmlValue){
that.htmlValue = "获取";
//开启禁用按钮
that.disabled = false;
//删除定时器
clearInterval(intervalId);
}
}, 1000);
//准备参数
let param = {"phone": this.user.phone};
//发送短信请求
this.$http.post("/verification/sendRegisterMobileCode", param).then((res) => {
let {success, msg} = res.data;
//提示用户一分钟以内不能连续发送多次
if(!success){
this.errorMsg = msg;
}
});
},
//校验手机号是否被注册了
checkPhone(){
//传递的参数
let param = {"phone": this.user.phone};
//发送请求校验手机号
this.$http.post("/user/checkPhone",param).then((res)=>{
let {success, msg} = res.data;
//后台响应success为false,就证明手机号已被注册
if(!success){
this.disabled = true;
this.errorMsg = msg;
console.debug(this.errorMsg);
}else{
//否则按钮应该是启用状态
this.disabled = false;
//清空错误信息
this.errorMsg = "";
}
})
}
}
});
</script>
</html>