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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 在Web项目中Email和短信验证是很普遍的情形,下面我们来介绍如何用Java来实现。

1.用JAVA实现Email验证


1.1 Java实现


EmailSender.java实现使用java来发送Email。


package com.jerry;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.AuthenticationFailedException;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
/**
 * 实现邮件发送功能
 * @author Administrator
 *
 */
public class EmailSender {
  private static final Logger logger = LogManager.getLogger(EmailSender.class);
  private String host; // 服务器地
  private String from; // 发件人
  private String to; // 收件人 多个收件人以,分隔
  private String title; // 主题
  private String content; // 内容
  private List<File> attachmentlist ; //附件集
  private String username; // 用户名
  private String password; // 密码
  /**发件人员工编号*/
  private String sendEmployeeId;  
  public String getSendEmployeeId() {
    return sendEmployeeId;
  }
  public void setSendEmployeeId(String sendEmployeeId) {
    this.sendEmployeeId = sendEmployeeId;
  }
  public String getHost() {
    return host;
  }
  public void setHost(String host) {
    this.host = host;
  }
  public String getFrom() {
    return from;
  }
  public void setFrom(String from) {
    this.from = from;
  }
  public String getTo() {
    return to;
  }
  public void setTo(String to) {
    this.to = to;
  }
  public String getTitle() {
    return title;
  }
  public void setTitle(String title) {
    this.title = title;
  }
  public String getContent() {
    return content;
  }
  public void setContent(String content) {
    this.content = content;
  }
  public List<File> getAttachmentlist() {
    return attachmentlist;
  }
  public void setAttachmentlist(List<File> attachmentlist) {
    this.attachmentlist = attachmentlist;
  }
  public String getUsername() {
    return username;
  }
  public void setUsername(String username) {
    this.username = username;
  }
  public String getPassword() {
    return password;
  }
  public void setPassword(String password) {
    this.password = password;
  }
  public String getPort() {
    return port;
  }
  public void setPort(String port) {
    this.port = port;
  }
  private String port;  
  public EmailSender(String host, String from, String to, String title,
      String content, List attachmentlist, String username, String password,String port) {
    this.host = host;
    this.from = from;
    this.to = to;
    this.title = title;
    this.content = content;
    this.attachmentlist = attachmentlist;
    this.username = username;
    this.password = password;
    this.port=port;
  }
  public EmailSender(String to, String title,
      String content, List attachmentlist) {
    this.to = to;
    this.title = title;
    this.content = content;
    this.attachmentlist = attachmentlist;
  }  
  /**
   * 发送邮件
   * @return 发送状态信息 index0:状态 0成功 1失败;index1:描述错误信息
   */
  public String[] sendMail(){
    String[] result=new String[2];
    Session session=null;
    Properties props = System.getProperties();
    props.put("mail.smtp.host", host);
    props.put("mail.smtp.sendpartial", "true");
    props.put("mail.smtp.port", port);
    if(StringUtils.isBlank(username)){//不需要验证用户名密码
      session = Session.getDefaultInstance(props, null);
    }else{
      props.put("mail.smtp.auth", "true");
      EmailAuthenticator auth = new EmailAuthenticator(username, password);
      session = Session.getInstance(props, auth); 
    }    
    //设置邮件发送信息
    try{
      // 创建邮件
      MimeMessage message = new MimeMessage(session);
      // 设置发件人地址
      message.setFrom(new InternetAddress(from));
      // 设置收件人地址(多个邮件地址)
      InternetAddress[] toAddr = InternetAddress.parse(to);
      message.addRecipients(Message.RecipientType.TO, toAddr);
      // 设置邮件主题
      message.setSubject(title);
      // 设置发送时间
      message.setSentDate(new Date());
      // 设置发送内容
      Multipart multipart = new MimeMultipart();
      MimeBodyPart contentPart = new MimeBodyPart();
      contentPart.setText(content);
      multipart.addBodyPart(contentPart);
      //设置附件
      if(attachmentlist!=null && attachmentlist.size()>0){
        for(int i = 0 ; i < attachmentlist.size();i++){
          MimeBodyPart attachmentPart = new MimeBodyPart();
          FileDataSource source = new FileDataSource(attachmentlist.get(i));
          attachmentPart.setDataHandler(new DataHandler(source));
          attachmentPart.setFileName(MimeUtility.encodeWord(attachmentlist.get(i).getName(), "gb2312", null));
          multipart.addBodyPart(attachmentPart);
        } 
      }
      message.setContent(multipart);      
      //登录SMTP服务器
      if (StringUtils.isBlank(username)) {
        // 不需验证
        Transport.send(message);
      } else {
        // 需要验证
        Transport transport = session.getTransport("smtp");
        transport.connect();
        transport.sendMessage(message, message.getAllRecipients());
        transport.close(); 
      }    
      result[0]="0";
      result[1]="发送成功";      
      logger.info("邮件发送成功!发送人:"+from);
    }catch(MessagingException mex){
      result[0]="1";
      result[1]="邮件服务器发生错误";    
      if(mex instanceof AuthenticationFailedException){
        result[1]="用户名或密码错误";
      }
    } catch (Exception e) {
      result[0]="1";
      result[1]="系统异常";
    }      
    return result;
  }  
  public static void main(String[] args){
    String SNMPTServer = "smtp.126.com";
    String from="xianggu625@126.com";
    String to="xianggu625@126.com";
    String title="发送测试报告";
    String content="附件为测试报告";
    String username="xianggu625@126.com";
    String password="VXDUKEHFKHMCKHRT";
    String port="25";
    List list=new ArrayList();
    //list.add(new File("C:\\myjava\\web\\junit.rar"));
    EmailSender sender=new EmailSender(SNMPTServer,from,to,title,content,list,username,password,port); 
    String [] result = sender.sendMail();
    System.out.println(result[1]+"ffffffffffffffff");
  }
}
/**
 * class MyAuthenticator用于邮件服务器认证 构造器需要用户名、密码作参数
 */
class EmailAuthenticator extends Authenticator {
  private String username = null;
  private String password = null;
  public EmailAuthenticator(String username, String password) {
    this.username = username;
    this.password = password;
  }
  public PasswordAuthentication getPasswordAuthentication() {
    return new PasswordAuthentication(username, password);
  }
}


1.2 邮件服务器端设置

注意:网易,QQ的邮箱password的设置为下图设置的密码。

 

image.png


用手机扫描后,页面会显示密码。

 

image.png


1.3 HTML代码


email.html


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>找回密码</title>
</head>
<form method="post" action="jsp/email.jsp" name="myForm">
  用户名:<input type="text" name="username" maxlength="50" value=""><br>
  邮箱:<input type="Email" name="Email" maxlength="50" value=""><br>
  <input type="submit" value="找回密码">
</form>
 </body>
</html>


1.4 jsp实现


email.jsp


<%@ page contentType="text/html; charset=gb2312" %>
<%@ page language="java" %>
<%@ page import="java.util.*" %>
<%@ page import="java.io.File" %>
<%@ page import="java.util.Random" %>
<%@ page import="com.mysql.jdbc.Driver" %>
<%@ page import="java.sql.*" %>
<%@ page import="com.jerry.EmailSender" %>
<%@ page import="cn.com.service.*" %>
<%@ include file="db/checkfromdb.jsp"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<%
String name=request.getParameter("username"); 
String to=request.getParameter("Email");
String code6 = String.valueOf(new Random().nextInt(999999));
String mycode=code.getSHA256StrJava(code6).toString();
Connection conn = connectDB();
ResultSet rs = getrs(name,to,"","",conn);
if(!(rs.getString("mycount")).equals("0")){
  String SNMPTServer = "smtp.126.com";
  String from="xianggu625@126.com"; 
  String title="找回验证码";
  String content="您的验证码为"+code6;
  String username="xianggu625@126.com";
  String password="DXDUYEHFJHMTKHRT";
  String port="25";
  List list=new ArrayList();
  EmailSender sender=new EmailSender(SNMPTServer,from,to,title,content,list,username,password,port); 
  String [] result = sender.sendMail();
  if (result[1].equals("发送成功")){
%>
<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>
<body>
<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("注册的用户名和Email不匹配,请<a href=\"../email.html\">,重新输入</a>");
}
%>


1.5 使用SH256散列


我们对使用到的6位随机密码进行SH256散列,这个方法在code.java中定义。

package cn.com.service;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class code {
  /**
  * 利用java原生的摘要实现SHA256加密
  * @param str 加密后的报文
  * @return
  */
  public static String getSHA256StrJava(String str){
   MessageDigest messageDigest;
   String encodeStr = "";
   try {
    messageDigest = MessageDigest.getInstance("SHA-256");
    messageDigest.update(str.getBytes("UTF-8"));
    encodeStr = byte2Hex(messageDigest.digest());
   } catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
   } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
   }
   return encodeStr;
  }
  /**
  * 将byte转为16进制
  * @param bytes
  * @return
  */
  private static String byte2Hex(byte[] bytes){
   StringBuffer stringBuffer = new StringBuffer();
   String temp = null;
   for (int i=0;i<bytes.length;i++){
    temp = Integer.toHexString(bytes[i] & 0xFF);
    if (temp.length()==1){
    //1得到一位的进行补0操作
    stringBuffer.append("0");
    }
    stringBuffer.append(temp);
   }
   return stringBuffer.toString();
  }
}


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

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


1.6 安全编码

为了安全性,方式用户在发包以后,黑客截包修改Email地址,所以需要获得Email地址后,需要校验是否与该用户注册的Email用户一致,所以在db目录下建立checkfromdb.jsp,完成这个功能。

<%@ page import="com.mysql.jdbc.Driver" %>
<%@ page import="java.util.*" %>
<%@ page import="java.sql.*" %>
<%@ page language="java" %>
<%@ page import="com.mysql.jdbc.Driver" %>
<%@ page import="java.sql.*" %>
<%!
  Connection connectDB(){
    Connection conn=null;
    try{
      //驱动程序名
      String driverName="com.mysql.jdbc.Driver";
      //数据库用户名
      String userName="root";
      //密码
      String userPasswd="123456";
      //数据库名
      String dbName="ebusiness";
      //联结字符串
      String url="jdbc:mysql://localhost/"+dbName+"?user="+userName+"&password="+userPasswd;
      Class.forName(driverName).newInstance(); 
      conn=DriverManager.getConnection(url);
    }catch(Exception e) {
      e.printStackTrace();
    }
    return conn;
  }
  ResultSet getrs(String name,String email,String phone,String password,Connection conn){
    ResultSet rs = null;
    try{
      //表名
      String tableName="goods_user"; 
      String sql = "";
      if(password.length()!=0){sql="select count(*) as mycount from "+tableName+" where username=? and password=?";}
      else if(email.length()!=0){sql="select count(*) as mycount from "+tableName+" where username=? and email=?";}
      else if(phone.length()!=0){sql="select count(*) as mycount from "+tableName+" where username=? and phone=?";} 
      PreparedStatement ps = conn.prepareStatement(sql);
      ps.setString(1,name);
      if(password.length()!=0)ps.setString(2,password);
      else if(email.length()!=0)ps.setString(2,email);
      else if(phone.length()!=0)ps.setString(2,phone);
      rs = ps.executeQuery();
      rs.next();
    }catch(Exception e) {
      e.printStackTrace();
    }
    return rs;
  }
%>
相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
6月前
|
存储 Java API
【Azure 存储服务】Java Storage SDK 调用 uploadWithResponse 代码示例(询问ChatGTP得代码原型后人力验证)
【Azure 存储服务】Java Storage SDK 调用 uploadWithResponse 代码示例(询问ChatGTP得代码原型后人力验证)
|
4月前
|
存储 网络协议 前端开发
在 Java 中如何完全验证 URL
在 Java 中如何完全验证 URL
123 8
|
4月前
|
运维 监控 搜索推荐
阿里大鱼进行发短信业务---使用详细步骤-Java操作
这篇文章详细介绍了如何在Java中使用阿里大鱼服务来发送短信,包括开通短信服务、签名和模板管理,以及具体的Java开发步骤和代码示例。
205 0
阿里大鱼进行发短信业务---使用详细步骤-Java操作
|
6月前
|
存储 算法 Java
在Java中使用MD5对用户输入密码进行加密存储、同时登录验证。
这篇文章详细介绍了在Java项目中如何使用MD5算法对用户密码进行加密存储和登录验证,包括加入依赖、编写MD5工具类、注册时的密码加密和登录时的密码验证等步骤,并通过示例代码和数据库存储信息展示了测试效果。
在Java中使用MD5对用户输入密码进行加密存储、同时登录验证。
|
6月前
|
存储 Java
如何在 Java 中验证 ArrayList?
【8月更文挑战第23天】
57 0
|
6月前
|
前端开发 Java
如何实现 Java SpringBoot 自动验证入参数据的有效性
如何实现 Java SpringBoot 自动验证入参数据的有效性
53 0
|
8月前
|
Oracle Java 关系型数据库
Java入门——开发环境、入门程序(搭建Java开发环境、安装JDK 验证、JDK、编写代码、编译代码、运行代码)
Java入门——开发环境、入门程序(搭建Java开发环境、安装JDK 验证、JDK、编写代码、编译代码、运行代码)
88 3
|
8月前
|
存储 NoSQL Java
Redis系列学习文章分享---第三篇(Redis快速入门之Java客户端--短信登录+session+验证码+拦截器+登录刷新)
Redis系列学习文章分享---第三篇(Redis快速入门之Java客户端--短信登录+session+验证码+拦截器+登录刷新)
144 0
|
8月前
|
Java API 数据处理
Java Bean参数验证:深入探索javax.validation.constraints注解
Java Bean参数验证:深入探索javax.validation.constraints注解
265 0
|
8月前
|
存储 算法 Java
【经典算法】LeetCode 125. 验证回文串(Java/C/Python3实现含注释说明,Easy)
【经典算法】LeetCode 125. 验证回文串(Java/C/Python3实现含注释说明,Easy)
50 0

热门文章

最新文章