用JAVA实现Email和短信验证(下)

简介: 用JAVA实现Email和短信验证(下)

1.7 操作界面

操作界面如下:

image.png

 

收到邮件

 

image.png


输入验证码268111,进入修改密码界面。

 

image.png


点击【提交】,可以设置新密码。

 

2.用JAVA实现短信验证


2.1 短信第三方平台设置


发送短信,需要使用第三方平台,这里我使用的是榛子网(http://sms_developer.zhenzikj.com/zhenzisms_user/index.html),注册登录进去,建议充20元钱,可以发送500条短信。

进入应用管理-我的应用,记住AppId和AppSecret,下面编码的时候要用。

 

image.png


进入短信管理-短信模板,记住模板ID,下面编码的时候要用。编辑内容。

 

image.png


注意:

1. 占位符格式:{数字},从{1}、{2}开始顺序填写。示例: 验证码:{1},{2}内有效,请勿泄漏给他人使用。

2. 每个账号最多创建20个模板

3. 个人账号创建的短信正文模板每个变量取值最多支持12个字。企业认证用户没有变量取值长度限制。

4. 模板中不能含有短信签名,比如【xx】

5. 模板必须体现实际业务,除变量以外的文本内容必须可判读短信含义和使用场景。

特别注意第1条,{1}、{2}我们将在程序中进行变量赋值。我的短信模板为:

“验证码为{1}:1分钟内有效,请勿泄漏给他人使用。”,里面仅有一个变量。

上代码。


2.2 Java代码


GetMessage.java

package cn.com.service;
import com.zhenzi.sms.ZhenziSmsClient;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
public class GetMessage { 
  //短信平台相关参数
  //这个不用改
  public static String getCode(String memPhone){
    String apiUrl = "https://sms_developer.zhenzikj.com";
    //榛子云系统上获取
    String appId = "109473";
    String appSecret = "3592cfbd-0877-4cac-b720-ac4a55cefc77";
    try {
      //随机生成验证码
      String code = String.valueOf(new Random().nextInt(999999));
      //将验证码通过榛子云接口发送至手机
      ZhenziSmsClient client = new ZhenziSmsClient(apiUrl, appId, appSecret);
      Map<String, Object> params = new HashMap<String, Object>();
      //前台输入的手机号
      params.put("number", memPhone);
      params.put("message", code);
      //这个模板id对应的是榛子云个人中心的模板id
      params.put("templateId", 5948);
      String[] templateParams = new String[1];
      templateParams[0] = code;
      params.put("templateParams", templateParams);
      String result = client.send(params);
      int length = result.toCharArray().length;
      result = result.substring(0,length-1)+",\"mycode\":\""+code+"\"}";
      return result;
    } catch (Exception e) {
      e.printStackTrace();
      return "";
    }
  }


在这里:

  • String appId = "109473"; //为榛子网的用户ID
  • String appSecret = "3592cfbd-0877-4cac-b720-ac4a55cefc77";//为榛子网的用户密码

  • params.put("templateId", 5948);//榛子网的模板ID
  • String[] templateParams = new String[1]; //向模板中传参数
  • templateParams[0] = code;


2.3 HTML代码


phone.html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>找回密码</title>
</head>
<body>
   <form method="post" name="myForm" action="jsp/sms.jsp">
     <div>用户名:<input type="text" name="username" maxlength="50" value=""></div>
       <div>手机号: <input type="tel" name="number"></div>
       <div><button type="submit" class="sub-btn">获取验证码</button></div>
   </form>
</body>
</html>


3.4 jsp实现


sms.jsp


<%@ page contentType="text/html; charset=gb2312" %>
<%@ page language="java" %>
<%@ page import="net.sf.json.JSONObject" %>
<%@ page import="com.mysql.jdbc.Driver" %>
<%@ page import="java.sql.*" %>
<%@ page import="cn.com.service.*" %>
<%@ include file="db/checkfromdb.jsp"%>
<!DOCTYPE html>
<%
String name=request.getParameter("username"); 
String number=request.getParameter("number");
Connection conn = connectDB();
ResultSet rs = getrs(name,"",number,"",conn);
if(!(rs.getString("mycount")).equals("0")){
  String message = GetMessage.getCode(number);
  JSONObject json = JSONObject.fromObject(message);
  if((json.get("code").toString()).equals("0")&&(json.get("data").toString()).equals("发送成功")){
    String mycode = json.get("mycode").toString();
    mycode=code.getSHA256StrJava(mycode);
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>输入验证码</title>
<script type="text/javascript" src="../js/sh256.js"></script>
<script type="text/javascript" >
function checkcode()
{
  var my = document.forms["myForm"]["jym"].value;
  if (my.length!=6){
   alert("验证码应该为6位!");
  return false;
  }
  my = SHA256(my);
  if(my!="<%=mycode%>"){
  alert("验证码错误!");
  return false;
  }else
  return true;
}
</script>
</head>
<form method="post" action="setpassword.jsp" name="myForm" onsubmit="return checkcode()">
  验证码:<input type="number" name="jym" maxlength="50" value=""><br>
  <input type="submit" value="提交">
</form>
 </body>
</html>
<%
session.setAttribute("code" , mycode);
}
session.setAttribute("uername" , name);
}else{
  out.print("注册的用户名和手机不匹配,请<a href=\"../phone.html\">,重新输入</a>");
}
%>


用户输入通过短信收到的6位编码,在JS端进行SH256编码后进行比对。

注:更安全的做法可以通过Ajax方法来实现。


3.5安全编码

为了安全性,方式用户在发包以后,黑客截包修改电话号码,所以需要获得电话号码后,需要校验是否与该用户注册的电话号码用户一致,同样调用checkfromdb.jsp中的函数,完成这个功能。


3.6 操作界面

操作界面如下:

 

image.png


手机收到验证码。

 

image.png


输入验证码

 

image.png


点击【提交】,可以设置新密码。

 

image.png


3.SH256 散列js代码实现


sh256.js


/**
*
* Secure Hash Algorithm (SHA256)
* http://www.webtoolkit.info/
*
* Original code by Angel Marin, Paul Johnston.
*
**/
function SHA256(s){
  var chrsz = 8;
  var hexcase = 0;
  function safe_add (x, y) {
    var lsw = (x & 0xFFFF) + (y & 0xFFFF);
    var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
    return (msw << 16) | (lsw & 0xFFFF);
  }
  function S (X, n) { return ( X >>> n ) | (X << (32 - n)); }
  function R (X, n) { return ( X >>> n ); }
  function Ch(x, y, z) { return ((x & y) ^ ((~x) & z)); }
  function Maj(x, y, z) { return ((x & y) ^ (x & z) ^ (y & z)); }
  function Sigma0256(x) { return (S(x, 2) ^ S(x, 13) ^ S(x, 22)); }
  function Sigma1256(x) { return (S(x, 6) ^ S(x, 11) ^ S(x, 25)); }
  function Gamma0256(x) { return (S(x, 7) ^ S(x, 18) ^ R(x, 3)); }
  function Gamma1256(x) { return (S(x, 17) ^ S(x, 19) ^ R(x, 10)); }
  function core_sha256 (m, l) {
    var K = new Array(0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786, 0xFC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x6CA6351, 0x14292967, 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2);
    var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19);
    var W = new Array(64);
    var a, b, c, d, e, f, g, h, i, j;
    var T1, T2;
    m[l >> 5] |= 0x80 << (24 - l % 32);
    m[((l + 64 >> 9) << 4) + 15] = l;
    for ( var i = 0; i<m.length; i+=16 ) {
      a = HASH[0];
      b = HASH[1];
      c = HASH[2];
      d = HASH[3];
      e = HASH[4];
      f = HASH[5];
      g = HASH[6];
      h = HASH[7];
      for ( var j = 0; j<64; j++) {
        if (j < 16) W[j] = m[j + i];
        else W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]);
        T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]);
        T2 = safe_add(Sigma0256(a), Maj(a, b, c));
        h = g;
        g = f;
        f = e;
        e = safe_add(d, T1);
        d = c;
        c = b;
        b = a;
        a = safe_add(T1, T2);
      }
      HASH[0] = safe_add(a, HASH[0]);
      HASH[1] = safe_add(b, HASH[1]);
      HASH[2] = safe_add(c, HASH[2]);
      HASH[3] = safe_add(d, HASH[3]);
      HASH[4] = safe_add(e, HASH[4]);
      HASH[5] = safe_add(f, HASH[5]);
      HASH[6] = safe_add(g, HASH[6]);
      HASH[7] = safe_add(h, HASH[7]);
    }
    return HASH;
  }
  function str2binb (str) {
    var bin = Array();
    var mask = (1 << chrsz) - 1;
    for(var i = 0; i < str.length * chrsz; i += chrsz) {
      bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i%32);
    }
    return bin;
  }
  function Utf8Encode(string) {
    string = string.replace(/\r\n/g,"\n");
    var utftext = "";
    for (var n = 0; n < string.length; n++) {
      var c = string.charCodeAt(n);
      if (c < 128) {
        utftext += String.fromCharCode(c);
      }
      else if((c > 127) && (c < 2048)) {
        utftext += String.fromCharCode((c >> 6) | 192);
        utftext += String.fromCharCode((c & 63) | 128);
      }
      else {
        utftext += String.fromCharCode((c >> 12) | 224);
        utftext += String.fromCharCode(((c >> 6) & 63) | 128);
        utftext += String.fromCharCode((c & 63) | 128);
      }
    }
    return utftext;
  }
  function binb2hex (binarray) {
    var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
    var str = "";
    for(var i = 0; i < binarray.length * 4; i++) {
      str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
      hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF);
    }
    return str;
  }
  s = Utf8Encode(s);
  return binb2hex(core_sha256(str2binb(s), s.length * chrsz));
}
目录
相关文章
|
2月前
|
存储 Java API
【Azure 存储服务】Java Storage SDK 调用 uploadWithResponse 代码示例(询问ChatGTP得代码原型后人力验证)
【Azure 存储服务】Java Storage SDK 调用 uploadWithResponse 代码示例(询问ChatGTP得代码原型后人力验证)
|
2月前
|
存储 算法 Java
在Java中使用MD5对用户输入密码进行加密存储、同时登录验证。
这篇文章详细介绍了在Java项目中如何使用MD5算法对用户密码进行加密存储和登录验证,包括加入依赖、编写MD5工具类、注册时的密码加密和登录时的密码验证等步骤,并通过示例代码和数据库存储信息展示了测试效果。
在Java中使用MD5对用户输入密码进行加密存储、同时登录验证。
|
5月前
|
JavaScript Java
java生成验证码并进行验证
java生成验证码并进行验证
|
2月前
|
存储 Java
如何在 Java 中验证 ArrayList?
【8月更文挑战第23天】
28 0
|
2月前
|
前端开发 Java
如何实现 Java SpringBoot 自动验证入参数据的有效性
如何实现 Java SpringBoot 自动验证入参数据的有效性
32 0
|
4月前
|
Oracle Java 关系型数据库
Java入门——开发环境、入门程序(搭建Java开发环境、安装JDK 验证、JDK、编写代码、编译代码、运行代码)
Java入门——开发环境、入门程序(搭建Java开发环境、安装JDK 验证、JDK、编写代码、编译代码、运行代码)
56 3
|
4月前
|
存储 NoSQL Java
Redis系列学习文章分享---第三篇(Redis快速入门之Java客户端--短信登录+session+验证码+拦截器+登录刷新)
Redis系列学习文章分享---第三篇(Redis快速入门之Java客户端--短信登录+session+验证码+拦截器+登录刷新)
68 0
|
4月前
|
Java API 数据处理
Java Bean参数验证:深入探索javax.validation.constraints注解
Java Bean参数验证:深入探索javax.validation.constraints注解
|
4月前
|
存储 算法 Java
【经典算法】LeetCode 125. 验证回文串(Java/C/Python3实现含注释说明,Easy)
【经典算法】LeetCode 125. 验证回文串(Java/C/Python3实现含注释说明,Easy)
20 0
|
5月前
|
Oracle Java 关系型数据库
Java 开发者必备:JDK 版本详解与选择策略(含安装与验证)
Oracle Java SE 支持路线图显示,JDK 8(LTS)支持至2030年,非LTS版本如9-11每6个月发布且支持有限。JDK 11(LTS)支持至2032年,而JDK 17及以上版本现在提供免费商用许可。LTS版本提供长达8年的支持,每2年发布一次。Oracle JDK与OpenJDK有多个社区和公司构建版本,如Adoptium、Amazon Corretto和Azul Zulu,它们在许可证、商业支持和更新方面有所不同。个人选择JDK时,可考虑稳定性、LTS、第三方兼容性和提供商支持。
3795 0
下一篇
无影云桌面