实现图片验证码与手机短信验证码:

1、HTML 代码:


<!-- 和验证码一样大小的提示图片:"请输入手机号" --><input type="hidden" value="${@cn.mycs.core.util.ToolUtil.url(@cn.mycs.core.constant.CommonConstant.DOMAINS_STATIC)}/2.0.0/images/safeCode.jpg" id="tipImageUrl">
<div class="form-group"><label for="" class="control-label col-sm-3">联系人手机:</label><div class="col-sm-9"><input maxlength="11" name="phone" placeholder="负责人手机" data="手机号码" warn="请输入11位数的手机号!" data-options="required:true" type="text" class="form-control easyui-validatebox" id="phone2"><span class="reg_warn" style="color: red;"></span></div></div><div class="form-group"><label for="" class="control-label col-sm-3">验证码:</label><div class="col-sm-9"><div class="row"><div class="col-sm-4"><input name="safeCode" id="safeCode2"  maxlength="4"  data="验证码" warn="4位字符的验证码!" type="text" data-options="required:true,tipPosition:'left'" class="form-control easyui-validatebox"></div><div class="col-sm-4"><img class="validate-img"  src="${@cn.mycs.core.util.ToolUtil.url(@cn.mycs.core.constant.CommonConstant.DOMAINS_STATIC)}/2.0.0/images/safeCode.jpg" id="validate-img2" /></div></div></div></div><div class="form-group"><label for="" class="control-label col-sm-3">短信验证码:</label><div class="col-sm-9"><div class="row"><div class="col-sm-4"><input name="smsCodeM" maxlength="6"  placeholder="6位验证码" data="手机验证码"   warn="请输入手机验证码!"  type="text" class="form-control  easyui-validatebox" /><span class="reg_warn" style="color: red;"></span></div><div class="col-sm-8"><button type="button" class="btn btn-primary" id="big_gray_btn2">发送验证码</button></div></div></div></div>

2、js代码:

//手机号输入事件$("input[name='phone']").keyup(function () {var _this = $(this), v = _this.val(), obj_safeCode = _this.parent().parent().next("div").find(".validate-img");if (_this.data("v") != v) {_this.data("v", v);/^1\d{10}$/.test(v) ? obj_safeCode.trigger("click") : obj_safeCode.attr("src", $("#tipImageUrl").val());}});//验证码点击事件$("#validate-img1").click(function () {var error = $(".reg_error");for (var i = 0; i < error.length; i++) {if (error.eq(0 + "").html()=="该手机号已被绑定") {return;}}var v = $("#phone1").val();$(this).parent().prev("div").find("input[name='safeCode']").val("");/^1\d{10}$/.test(v) && $(this).attr("src", _ctx + "/validateCode?refresh=" + Math.random());});//发送(手机|邮箱)验证码$("#big_gray_btn1").click(function () {var error = $(".reg_error");for (var i = 0; i < error.length; i++) {if (error.eq(0 + "").html()=="该手机号已被绑定") {alert("该手机号已被绑定","error");return;}}var _this = $(this), txt = _this.text(), div = _this.closest("div");if (txt == "发送验证码") {var tel_input = $("#phone1");var safeCode = $("#safeCode1").val();var tel_mess = tel_input.parent().nextAll("span").text();var tel = tel_input.val();if (tel_mess == "该号码已被绑定") {alert("请重新输入手机号码", "error");} else if (!/^[a-zA-Z0-9]{4}$/.test(safeCode)) {alert("请先输入正确的验证码!", "error");} else if (/^1\d{10}$/.test(tel)) {_this.text("请稍候……");_this.nextAll("span").hide();$.getJSON(_ctx + "/app/mobileSms?action=send&captchaCode=" + safeCode + "&phone=" + tel + "&" + Math.random(), function (json) {_this.text(txt);if (1 != json.code) {alert(json.message, "error");if (json.message == "图形验证码错误") {$("#validate-img1").click();}} else {setT(_this, 180, txt);div.nextAll("span").text("此手机验证码30分钟内有效").attr({"class": "reg_warn"}).show();}});} else {div.css("border-color", "#dedede").nextAll("span").text("请先输入正确的手机号!").attr({"class": "reg_warn"});tel_input.focus().parent().css("border-color", "#f77979").nextAll("span").attr("class", "reg_error");}}});

3、发送短信 控制器 Controller:

package cn.wpg.client.web.controller.persional;import cn.wpg.core.base.restful.JsonResult;
import cn.wpg.core.constant.MobileProperties;
import cn.wpg.core.support.StrKit;
import cn.wpg.core.util.MobileSmsUtil;
import cn.wpg.server.persistence.redis.RedisService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletRequest;
import java.util.Random;/*** <p>发送短信 控制器 Controller</p>* <pre>* @author Wupeiguo* @date 2019/06/14 11:42* </pre>*/
@Controller
public class MobileSmsController {private final Logger log = LoggerFactory.getLogger(getClass());@Autowiredprivate RedisService redisService;@RequestMapping("/app/mobileSms")@ResponseBodypublic JsonResult mobileSms(String action, String captchaCode, String phone, HttpServletRequest request) {if (StrKit.isEmpty(action) || StrKit.isEmpty(phone)) {log.debug("参数错误");return JsonResult.error("参数错误");}//获取redis 图形验证码做校验String code = redisService.get("cookiesReplyKey", 8, String.class);if (StrKit.isEmpty(code)) {log.debug("请重新获取图形验证码");return JsonResult.error("请重新获取图形验证码");} else if (!code.equalsIgnoreCase(captchaCode)) {log.debug("图形验证码错误");return JsonResult.error("图形验证码错误");} else if ("sendCode".equals(action)) {return sendCode(phone);}return JsonResult.success("发送成功");}private JsonResult sendCode(String phone) {log.debug("发送手机验证码");String key = "smsCode_" + phone;Object redisCode = redisService.get(key, Object.class);if (redisCode != null) {log.info("稍后再试");return JsonResult.error("稍后再试");}//生成随机号码final String smsCode = getRandomCode();//发送短信验证码JsonResult result = MobileSmsUtil.send(MobileProperties.SMS_APPID, phone, MobileProperties.SMS_TEMPLATEID, smsCode, "json");if (result.getCode() == 1) {redisService.set(key, smsCode, 120);log.info("发送短信验证码成功");return JsonResult.success("发送成功");} else {log.info("发送短信验证码失败");return JsonResult.error("发送失败");}}/**** 生成随机号码 6位* @return*/private String getRandomCode() {Random random = new Random();StringBuilder sb = new StringBuilder();for (int i = 0; i < 6; i++) {sb.append(random.nextInt(10));}return sb.toString();}
}

4、发送短信相关的配置 Properties:

package cn.wpg.core.constant;import cn.wpg.core.util.MD5Util;import java.util.Base64;
import java.util.Date;/*** <p>发送短信相关的配置 Properties</p>* <pre>* @author Wupeiguo* @date 2019/06/14 11:42* </pre>*/
public class MobileProperties {/*** API请求地址*/private static final String SMS_BASE_URL = "https://api.XXX.com/";/*** 云之讯REST API版本号。当前版本号为:2014-06-30*/private static final String SMS_SOFTVERSION = "2014-06-30";/*** 开发者账号ID。由32个英文字母和阿拉伯数字组成的开发者账号唯一标识符。*/private static final String SMS_ACCOUNT_SID = "96ea71afc8a76e978cbc13f67a4aa624";/*** 开发者账号TOKEN*/private static final String SMS_TOKEN = "c59ff426f4c88a2dc0e612a6c860b144";private static String timestamp;public static final String SMS_APPID = "5edd47ba7fa84465a90c1d08ac8c9547";public static final String SMS_TEMPLATEID = "51730";/*** @return string* 验证参数,URL后必须带有sig参数,sig= MD5(账户Id + 账户授权令牌 + 时间戳,共32位)(注:转成大写)*/private static String getSigParameter() {String sig = SMS_ACCOUNT_SID + SMS_TOKEN + timestamp;sig = MD5Util.encrypt(sig);return sig.toUpperCase();}private static String getTimestamp() {return format(new Date(), "yyyyMMddHHmmss");}public static String getSendSmsUrl() {timestamp=getTimestamp();return SMS_BASE_URL + SMS_SOFTVERSION + "/Accounts/" + SMS_ACCOUNT_SID + "/Messages/templateSMS?sig=" + getSigParameter();}public static String getAuthorization() {String data = SMS_ACCOUNT_SID + ":" + timestamp;return Base64.getEncoder().encodeToString(data.getBytes());}/*** 根据特定格式格式化日期** @param date   被格式化的日期* @param format 格式* @return 格式化后的字符串*/public static String format(Date date, String format) {return new SimpleDateFormat(format).format(date);}}
 

5、手机发送短信工具 Util:

package cn.wpg.core.util;import cn.wpg.core.base.restful.JsonResult;
import cn.wpg.core.constant.MobileProperties;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;/*** <p>手机发送短信工具 Util</p>* <pre>* @author Wupeiguo* @date 2019/06/14 11:42* </pre>*/
public class MobileSmsUtil {public static JsonResult send(String appId, String phone, String templateId, String smsCode, String type) {String sendSmsUrl = MobileProperties.getSendSmsUrl();String body;if ("json".equals(type)) {JSONObject json = new JSONObject();Map<String, String> bodyMap = new HashMap<>(4);bodyMap.put("appId", appId);bodyMap.put("templateId", templateId);bodyMap.put("appId", appId);bodyMap.put("to", phone);bodyMap.put("param", smsCode);json.put("templateSMS", bodyMap);body = json.toJSONString();} else if ("xml".equals(type)) {String bodyXml = "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>" +"<templateSMS>" +"<templateId>" + templateId + "</templateId>" +"<to>" + phone + "</to>" +"<param>" + smsCode + "</param>" +"<appId>" + appId + "</appId>" +"</templateSMS>";body = bodyXml;} else {throw new RuntimeException("只能json或xml,默认为json");}String result = doSend(sendSmsUrl, body, type);return result == null ?JsonResult.error("发送失败"):JsonResult.success(result);}private static String doSend(String url, String body, String type) {String mine;if ("json".equals(type)) {mine = "application/json";} else {mine = "application/xml";}Map<String, String> header = new HashMap<>(3);header.put("Accept", mine);header.put("Content-Type", mine + ";charset=utf-8");header.put("Authorization", MobileProperties.getAuthorization());return HdoPost(url, body, header);}private static String HdoPost(String url, String body, Map<String, String> header) {HttpClient httpClient;HttpPost postMethod;HttpResponse response;try {httpClient = HttpClients.createDefault();//传入URL地址postMethod = new HttpPost(url);//设置请求头if (header != null) {for (Map.Entry<String, String> entry : header.entrySet()) {//设置请求头postMethod.addHeader(entry.getKey(), entry.getValue());}}// 传入请求参数postMethod.setEntity(new StringEntity(body, Charset.forName("UTF-8")));// 获取响应response = httpClient.execute(postMethod);int statusCode = response.getStatusLine().getStatusCode();System.out.println("HTTP Status Code:" + statusCode);if (statusCode != HttpStatus.SC_OK) {System.out.println("HTTP请求未成功!HTTP Status Code:" + response.getStatusLine());return null;}HttpEntity httpEntity = response.getEntity();String reponseContent = EntityUtils.toString(httpEntity);// 释放资源EntityUtils.consume(httpEntity);System.out.println("响应内容:" + reponseContent);} catch (Exception e) {e.printStackTrace();}return "";}
}

6、MD5加密类(封装jdk自带的md5加密方法):

package cn.wpg.core.util;import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;/*** MD5加密类(封装jdk自带的md5加密方法)* @author zhangzhc * @date 2018-06-07 10:57:38*/
public class MD5Util {/*** 安全码*/public static final String SECURITY_CODE = "wha3202343222dxssssssswwd";/*** md5加密密码** @param source 源数据* @param salt   盐* @return String*/public static String encryptAndSalt(String source, String salt) {salt = (salt != null ? salt : "") + SECURITY_CODE;source = MD5Util.encrypt(source) + salt;return MD5Util.encrypt(source);}/*** md5加密** @param source 源数据* @return String*/public static String encrypt(String source) {return encodeMd5(source.getBytes());}private static String encodeMd5(byte[] source) {try {return encodeHex(MessageDigest.getInstance("MD5").digest(source));} catch (NoSuchAlgorithmException e) {throw new IllegalStateException(e.getMessage(), e);}}private static String encodeHex(byte[] bytes) {StringBuffer buffer = new StringBuffer(bytes.length * 2);for (int i = 0; i < bytes.length; i++) {if (((int) bytes[i] & 0xff) < 0x10) {buffer.append("0");}buffer.append(Long.toString((int) bytes[i] & 0xff, 16));}return buffer.toString();}public static void main(String[] args) {System.out.println(encrypt("123456"));}
}

7、备注:

jar包:

com.alibaba.fastjson:
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${fastjson.version}</version>
</dependency>org.apache.http:
<dependency><groupId>org.apache.activemq</groupId><artifactId>activemq-http</artifactId>
</dependency>

结果类 JsonResult:

该操作结果类为自定义类,可以用  Object 类型替代

获取图形验证码:

在《图形验证码》篇

实现图片验证码与手机短信验证码相关推荐

  1. Flask项目实战——6—(前台用户模型、前台登录注册、图形验证码、手机短信验证码、添加表单验证短信验证码请求)

    1.前台用户模型 前台用户模型定义 创建前台模型文件 apps/front/models.py # -*- encoding: utf-8 -*- """ @File : ...

  2. Java调用WebService接口实现发送手机短信验证码功能,java 手机验证码,WebService接口调用...

    近来由于项目需要,需要用到手机短信验证码的功能,其中最主要的是用到了第三方提供的短信平台接口WebService客户端接口,下面我把我在项目中用到的记录一下,以便给大家提供个思路,由于本人的文采有限, ...

  3. Atitit. 破解  拦截 绕过 网站 手机 短信 验证码  方式 v2 attilax 总结

    Atitit. 破解  拦截 绕过 网站 手机 短信 验证码  方式 v2 attilax 总结 1. 验证码的前世今生1 1.1. 第一代验证码 图片验证码1 1.2. 第二代验证码  用户操作 , ...

  4. Java调用WebService接口实现发送手机短信验证码功能

    为什么80%的码农都做不了架构师?>>>    一.样式示例: 二.前台的注册页面的代码:reg.jsp <%@ page language="java" ...

  5. java调接口实现发送手机短信验证码功能,手机验证码,接口调用

    原文地址:  http://blog.csdn.net/sxdtzhaoxinguo/article/details/34437591 近来由于项目需要,需要用到手机短信验证码的功能,其中最主要的是用 ...

  6. 手机短信验证码登录功能的开发实录(机器识别码、短信限流、错误提示、发送验证码倒计时60秒)

    短信验证码登录功能 项目分析 核心代码 1.外部js库调用 2.HTML容器构建 3.javaScript业务逻辑验证 4.后端验证逻辑 总结 短信验证码是通过发送验证码到手机的一种有效的验证码系统, ...

  7. H5学习之路-手机短信验证码的实现

    在上一篇博文中,给大家介绍了图片验证码的实现,今天再给大家介绍一下手机短信验证码的实现.其实,这个和图片验证码差不多,只不过要把后天生成的验证码发到对应的手机号码上,然后再进行验证.这里,关于发短信的 ...

  8. SpringBoot整合手机短信验证码

    手机短信验证码技术 1.流程图 前端点击发送手机验证码 后端判断恶意请求拦截[手机号码限制次数 - redis设置过期时间,自增 - 大于10次直接抛异常 - 没有做] 验证图形验证码是否正确,不正确 ...

  9. 手机短信验证码真的安全吗?

    手机的蓬勃发展,衍生出来众多行业,也让原本功能单一的手机号做出极大的改变.如今似乎每个人的手机号都绑定了或多或少的各种账号,手机绑定的东西越来越多,涉及到的重要的东西也越来越多,例如像银行卡绑定手机号 ...

  10. QPW 手机短信验证码发送日志表(tf_sms_send_log)

    文章目录 手机短信验证码发送日志表 需求说明 手机短信验证码发送日志表 CREATE TABLE `tf_sms_send_log` (`send_id` bigint(11) NOT NULL AU ...

最新文章

  1. 民政部部长李纪恒:适龄人口生育意愿偏低,总和生育率破警戒线
  2. android的窗口机制分析------事件处理
  3. .Net开发中报表工具选择的体会心得
  4. android root权限函数,android 4.4下app永久获取root权限的方法
  5. VB6 中 善用 ByRef 提升速度
  6. sublime3定制化为python3编辑利器。
  7. The King’s Problem 强连通
  8. layui表格使用复选框批量删除_layui表格数据复选框回显设置方法,表格复选框...
  9. JavaScript开发者应懂的33个概念js-33-concepts
  10. spring data jpa 之初体验
  11. 婚礼邀请函微信小程序
  12. I/O多路复用select服务器
  13. 计算机会议等级排名,中国计算机学会推荐国际学术期刊(搬运于中国计算机学会)
  14. jQuery ajax 文件下载
  15. torch_points_kernels遭遇 ModuleNotFoundError: No module named ‘torch_points_kernels.points_cpu‘
  16. java计算机毕业设计网上拍卖系统源码+系统+数据库+lw文档+mybatis+运行部署
  17. 回溯法解01背包问题(最通俗易懂,附C++代码)
  18. php三年级英语,三年级英语拼词大赛
  19. BMA250传感器驱动
  20. Route [register] not defined. 的解决办法

热门文章

  1. HAMA 混合信道接入Ad-Hoc,分布式TDMA 协议
  2. 一款高品质回音消除 模块 : F-23
  3. 增长工程日 | 从战略到战术,如何搭建新消费品牌增长体系
  4. Excel图表的用法及效果
  5. 个人用户永久免费,可自动升级版Excel插件,使用VSTO开发,Excel催化剂功能第5波-使用DAX查询从PowerbiDeskTop中获取数据源...
  6. 【DZX修改】根据性别不同显示不同的默认头像
  7. vue用mand-mobile ui做交易所移动版实战示例
  8. 熔断机制什么意思_熔断机制是什么意思
  9. Reservior Sampling (蓄水池抽样算法)
  10. android 两张电信_双卡双待双核2.3 电信机皇摩托XT882评测