SpringBoot实现短信验证码校验方法思路详解

有关阿里云通信短信服务验证码的发送,请参考我的另一篇文章   Springboot实现阿里云通信短信服务有关短信验证码的发送功能

思路

用户输入手机号后,点击按钮获取验证码。并设置冷却时间,防止用户频繁点击。

后台生成验证码并发送到用户手机上,根据验证码、时间及一串自定义秘钥生成MD5值,并将时间也传回到前端。

用户输入验证码后,将验证码和时间传到后台。后台先用当前时间减去前台传过来的时间验证是否超时。如果没有超时,就用用户输入的验证码 + 时间 + 自定义秘钥生成MD5值与之前的MD5值比较,如果相等则验证码校验通过,如果不等则说明验证码输入错误校验失败。

原理有点像解方程:

xyz经过一种不可逆运算得到A,将y和A传给用户,z后台保留,用户填写x1后,将x1 y A传回后台,后台再用x1 y z经过不可逆运算得到A1,如果A1和A相等,则验证码校验通过。

前端的实现

本例基于BootStrap,html代码中有BootStrap样式。如果你不想用BootStrap,可以将class样式去掉。效果如图所示。

html代码如下:

<div class="form-group has-feedback">
 <input type="tel" class="form-control" id="phone" placeholder="请输入手机号" maxlength=11>
 <span class="glyphicon glyphicon-earphone form-control-feedback"></span>
</div>
<div class="row">
 <div class="col-xs-6 pull_left">
  <div class="form-group">
   <input class="form-control" id="msg_num" placeholder="请输入验证码">
  </div>
 </div>
 <div class="col-xs-6 pull_center">
  <div class="form-group">
   <input type="button" class="btn btn-block btn-flat" id="verify_refresh" onclick="getMsgNum(this)" value="免费获取验证码">
  </div>
 </div>
</div>
<div class="col-xs-12 pull_center">
 <button type="button" class="btn btn-block btn-flat" onclick="validateNum()">验证</button>
</div>

js代码(基于jQuery)

var messageData;
var wait = 120; // 短信验证码120秒后才可获取下一个
/**
 * 获取验证码
 * @param that
 */
function getMsgNum(that) {
 var phoneNumber = $('#phone').val();
 setButtonStatus(that); // 设置按钮倒计时
 var obj = {
  phoneNumber: phoneNumber
 };
 $.ajax({
  url: httpurl + '/sendMsg', // 后台短信发送接口
  type: 'POST',
  dataType: 'json',
  contentType: "application/json",
  async: false, //false 同步
  data: JSON.stringify(obj),
  xhrFields: {
   withCredentials: true
  },
  success: function (result) {
   if(result.code == '200') {
    messageData = result.data;
   }else {
    alert("错误码:" + data.code + " 错误信息:" + data.message);
   }
  },
  error: function (XMLHttpRequest, textStatus, errorThrown) {
   console.log(XMLHttpRequest.status);
   console.log(XMLHttpRequest.readyState);
   console.log(textStatus);
  }
 });
}
/**
 * 设置按钮状态
 */
function setButtonStatus(that) {
 if (wait == 0) {
  that.removeAttribute("disabled");
  that.value="免费获取验证码";
  wait = 60;
 } else {
  that.setAttribute("disabled", true);
  that.value=wait+"秒后可以重新发送";
  wait--;
  setTimeout(function() {
   setButtonStatus(that)
  }, 1000)
 }
}
/**
* 注册按钮
*/
function validateNum() {
 var data = {
  msgNum: inputMsgNum,
  tamp: messageData.tamp,
  hash: messageData.hash
 };
 $.ajax({
  url: httpurl + '/validateNum', // 验证接口
  type: 'POST',
  dataType: 'json',
  contentType: "application/json",
  data: JSON.stringify(data),
  async: false, //false 同步
  success: function (data) {
   //业务处理
  },
  error: function (XMLHttpRequest, textStatus, errorThrown) {
   console.log(XMLHttpRequest.status);
   console.log(XMLHttpRequest.readyState);
   console.log(textStatus);
  }
 });
}

其中setButtonStatus()方法用于设置按钮冷却状态。效果如下图

后台的实现

private static final String KEY = "abc123"; // KEY为自定义秘钥
@RequestMapping(value = "/sendMsg", method = RequestMethod.POST, headers = "Accept=application/json")
public Map<String, Object> sendMsg(@RequestBody Map<String,Object> requestMap) {
String phoneNumber = requestMap.get("phoneNumber").toString();
String randomNum = CommonUtils.createRandomNum(6);// 生成随机数
SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
Calendar c = Calendar.getInstance();
c.add(Calendar.MINUTE, 5);
String currentTime = sf.format(c.getTime());// 生成5分钟后时间,用户校验是否过期
sengMsg(); //此处执行发送短信验证码方法
String hash = MD5Utils.getMD5Code(KEY + "@" + currentTime + "@" + randomNum);//生成MD5值
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("hash", hash);
resultMap.put("tamp", currentTime);
return resultMap; //将hash值和tamp时间返回给前端
}
@RequestMapping(value = "/validateNum", method = RequestMethod.POST, headers = "Accept=application/json")
public Map<String, Object> validateNum(@RequestBody Map<String,Object> requestMap) {
String requestHash = requestMap.get("hash").toString();
String tamp = requestMap.get("tamp").toString();
String msgNum = requestMap.get("msgNum").toString();
String hash = MD5Utils.getMD5Code(KEY + "@" + tamp + "@" + msgNum);
if (tamp.compareTo(currentTime) > 0) {
if (hash.equalsIgnoreCase(requestHash)){
//校验成功
}else {
//验证码不正确,校验失败
}
} else {
// 超时
}
}

总结

以上所述是小编给大家介绍的SpringBoot实现短信验证码校验方法思路详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • SpringBoot 集成Kaptcha实现验证码功能实例详解

    在一个web应用中验证码是一个常见的元素.不管是防止机器人还是爬虫都有一定的作用,我们是自己编写生产验证码的工具类,也可以使用一些比较方便的验证码工具.在网上收集一些资料之后,今天给大家介绍一下kaptcha的和springboot一起使用的简单例子. 准备工作: 1.你要有一个springboot的hello world的工程,并能正常运行. 2.导入kaptcha的maven: <!-- https://mvnrepository.com/artifact/com.github.penggl

  • Springboot实现阿里云通信短信服务有关短信验证码的发送功能

    前言 短信验证码是通过发送验证码到手机的一种有效的验证码系统.主要用于验证用户手机的合法性及敏感操作的身份验证. 现在市面上的短信服务平台有很多.大家在选择的时候未免会有些不好抉择.本人建议选择短信服务商应遵循以下几点: 服务商知名度高,业务流量大.(这样的平台可信度高) 服务稳定,不能经常宕机.(保证自身业务的流畅运行) 文档全面详细.(没文档怎么玩?) 最近的一个项目中,注册和修改密码时需要用到短信验证码校验手机号的功能.本人也是对比几家后,直接选择阿里云通信的短信服务.(本身项目服务器也是

  • Spring Boot项目利用Redis实现集中式缓存实例

    在高并发请求的web服务架构中,随着数据量的提升,缓存机制为绝大多数的后台开发所使用.这篇文章主要介绍如何在Spring Boot项目中为Entity添加利用Redis实现的集中式缓存. 1. 利用Spring Initializr来新建一个spring boot项目 2. 在pom.xml中添加redis.mysql和cache等相关依赖.一般情况下,缓存一般是在大规模数据库存储下所需要的 <dependency> <groupId>org.springframework.boo

  • 登陆验证码kaptcha结合spring boot的用法详解

    前言 在我们用户登录的时候,为了安全性考虑,会增加验证码的功能,这里采用的是google的kaptcha:spirngboot是轻便,独立,使得基于spring的应用开发变得特别简单.网上有很多介绍springboot的介绍,这里不多说. 言归正抓,讲下登陆时验证码结合springboot的用法 引入kaptcha所需要的jar包,我这里用的是maven <dependency> <groupId>com.github.penggle</groupId> <art

  • 详解Spring boot使用Redis集群替换mybatis二级缓存

    1 . pom.xml添加相关依赖 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> </parent> <!-- 依赖 --> <dependencies> &l

  • Spring Boot 验证码的生成和验证详解

    前言 本文介绍的imagecode方法是一个生成图形验证码的请求,checkcode方法实现了对这个图形验证码的验证.从验证码的生成到验证的过程中,验证码是通过Session来保存的,并且设定一个验证码的最长有效时间为5分钟.验证码的生成规则是从0~9的数字中,随机产生一个4位数,并增加一些干扰元素,最终组合成为一个图形输出 1.验证码生成类 import java.awt.*; import java.awt.image.BufferedImage; import java.io.Output

  • 实例详解Spring Boot实战之Redis缓存登录验证码

    本章简单介绍redis的配置及使用方法,本文示例代码在前面代码的基础上进行修改添加,实现了使用redis进行缓存验证码,以及校验验证码的过程. 1.添加依赖库(添加redis库,以及第三方的验证码库) <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</artifactId> </dependency&

  • Spring Boot集成Redis实现缓存机制(从零开始学Spring Boot)

    本文章牵涉到的技术点比较多:spring Data JPA.Redis.Spring MVC,Spirng Cache,所以在看这篇文章的时候,需要对以上这些技术点有一定的了解或者也可以先看看这篇文章,针对文章中实际的技术点在进一步了解(注意,您需要自己下载Redis Server到您的本地,所以确保您本地的Redis可用,这里还使用了MySQL数据库,当然你也可以内存数据库进行测试).这篇文章会提供对应的Eclipse代码示例,具体大体的分如下几个步骤: (1)新建Java Maven Pro

  • 详解Spring Boot使用redis实现数据缓存

    基于spring Boot 1.5.2.RELEASE版本,一方面验证与Redis的集成方法,另外了解使用方法. 集成方法 1.配置依赖 修改pom.xml,增加如下内容. <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> 2.配置R

  • Spring Boot 基于注解的 Redis 缓存使用详解

    看文本之前,请先确定你看过上一篇文章<Spring Boot Redis 集成配置>并保证 Redis 集成后正常可用,因为本文是基于上文继续增加的代码. 一.创建 Caching 配置类 RedisKeys.Java package com.shanhy.example.redis; import java.util.HashMap; import java.util.Map; import javax.annotation.PostConstruct; import org.springf

  • 详解SpringBoot集成Redis来实现缓存技术方案

    概述 在我们的日常项目开发过程中缓存是无处不在的,因为它可以极大的提高系统的访问速度,关于缓存的框架也种类繁多,今天主要介绍的是使用现在非常流行的NoSQL数据库(Redis)来实现我们的缓存需求. Redis简介 Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件,Redis 的优势包括它的速度.支持丰富的数据类型.操作原子性,以及它的通用性. 案例整合 本案例是在之前一篇SpringBoot + Mybatis + RESTful的基础上来集

  • Spring Boot中使用Redis做缓存的方法实例

    前言 本文主要给大家介绍的是关于Spring Boot中使用Redis做缓存的相关内容,这里有两种方式: 使用注解方式(但是小爷不喜欢) 直接<Spring Boot 使用 Redis>中的redisTemplate 下面来看看详细的介绍: 1.创建UserService public interface UserService { public User findById(int id); public User create(User user); public User update(U

随机推荐