栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

邮箱验证流程与token生成

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

邮箱验证流程与token生成

该过程仅供参考,若有优化与建议,欢迎提出。

目录
  • 依赖
  • 邮箱验证
    • 邮箱工具类
    • 检查邮箱格式
    • Cache缓存
    • SendEmail方法
  • token 生成

依赖
		
      	
      		javax.mail
      		mail
      		1.4.7
    	
		
      	
    		com.google.guava
    		guava
    		28.2-jre
    	
邮箱验证 邮箱工具类

此处用的是线程的方式,Callable更容易设置是否超时

import java.util.Date;
import java.util.Properties;
import java.util.concurrent.Callable;


import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class SEmail implements Callable{
	private static String USERNAME = "";//邮箱地址XXX@XX.XX
	
	private static String PASSWORD = "";//填写你的邮箱的授权码
	private static String HOST = "";//选择一个可用的服务器
	private String email;//目标邮箱
	private String code;//生成的验证码
	
	
	public SEmail(String email,String code){
		this.email = email;
		this.code = code;
	}
	public Boolean call() throws Exception{
		Transport transport = null;
		Properties prop = new Properties();
		prop.setProperty("mail.smtp.host", HOST);
		prop.setProperty("mai.transport.protocol", "smtp");
		prop.setProperty("mail.smtp.auth","true");
		Session session = Session.getDefaultInstance(prop);
		MimeMessage message = new MimeMessage(session);
		message.setFrom(new InternetAddress(USERNAME));
		message.setRecipient(Message.RecipientType.TO,new InternetAddress(email));
		message.setSentDate(new Date());
		message.setSubject("邮件验证码");
		String info = "rn" + 
				"rn" + 
				"	rn" + 
				"	验证码rn" + 
				"rn" + 
				"	rn" + 
				"	欢迎您使用XXX,这是您的验证码,请于X分钟内输入激活码rn" + 
				"	

"+ code +"

"+ " rn" + ""; message.setContent(info,"text/html;charset=UTF-8"); message.saveChanges(); session.setDebug(false); transport = session.getTransport("smtp"); transport.connect(USERNAME,PASSWORD); transport.sendMessage(message, message.getAllRecipients()); return true; } }
检查邮箱格式
public class CheckData {
    private static String NUM = ".*\d+.*";
    private static String SMALL = ".*[a-zA-Z]+.*";
    private static String CAPTIAL= ".*[a-zA-Z]+.*";
    private static String SYMBOL = ".*([~!@#$%^&*()_+|<>,.?/:;'\[\]{\\}\"]){1,}+.*";
    private static String EMAIL = "(\w+([-.][A-Za-z0-9]+)*){3,18}@\w+([-.][A-Za-z0-9]+)*\.\w+([-.][A-Za-z0-9]+)*";
    
	public static boolean checkEmail(String email) {
		 if (email != null) {
	            return email.matches(EMAIL);
	        }
		 return false;
	}
	
	public static boolean checkPass(String password) {
		if (password == null){
			return false;
		}
		int size = password.length();
		if(size < 6||size >16) {
			return false;
		}
		if(password.matches(SYMBOL)) {
			return false;
		}
	    int n =  (password.matches(SMALL) ? 1 : 0) + (password.matches(NUM) ? 1 : 0) + (password.matches(CAPTIAL) ? 1 : 0);
	    return n==3;  
	}
}

Cache缓存

使用谷歌的一款包

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.util.concurrent.TimeUnit;

public class VerifyCodeCache {
	
    private static volatile Cache codeCache;

    private VerifyCodeCache(){}

    public static Cache getCodeCache() {
       	//单例,懒汉模式
    	//双验证+同步锁
        if (codeCache == null) {
            synchronized (VerifyCodeCache.class) {
                if (codeCache == null) {
                    codeCache = CacheBuilder.newBuilder()
                            .expireAfterAccess(5, TimeUnit.MINUTES)
                            .maximumSize(100)
                            .concurrencyLevel(50).build();
                }
            }
        }
        return codeCache;
    }
}



SendEmail方法
	
	private ExecutorService executor = Executors.newFixedThreadPool(10); 
	
	private Cache codeCache = VerifyCodeCache.getCodeCache();
	@ResponseBody
	@RequestMapping("")
	public String sendEmail(String email){
		...
		if(!CheckData.checkEmail(email)) {
			resMessage.setAll(StatusCode.send_fail,"邮箱错误");
			...
		}
		StringBuilder builder = new StringBuilder();
		Random random = new Random();
		for(int i = 0 ; i<8;i++) {
			builder.append(random.nextInt(9));
		}
		Future future = executor.submit(new SEmail(email,builder.toString()));
		try {
			//等待30秒,未执行完成,抛出中断异常
			future.get(30, TimeUnit.SECONDS);
			//放入对应邮箱以及验证码
			codeCache.put(email, builder.toString());
			...
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.getStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.getStackTrace();
		} catch (TimeoutException e) {
			// TODO Auto-generated catch block
			e.getStackTrace();
		}
		...
	}
token 生成

此处用的是Java自带的加密模式,以及自己的加密密钥
注意,UTF-8的byte与String 相互转换会不一样,因为无法表示,因此,使用的是ISO-8859-1

 private final static Key SECRET_KEY = new SecretKeySpec("密钥内容".getBytes(),"AES");
	
	public static String createToken(String uuid) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
		//获取当前时间
		long currentTimeMillis = System.currentTimeMillis();
		
		String token = uuid + ":"+(currentTimeMillis + TIME_OUT);
	    Cipher cipher = Cipher.getInstance("AES");
	    cipher.init(Cipher.ENCRYPT_MODE, SECRET_KEY);
	    return new String(cipher.doFinal(token.getBytes()),"ISO-8859-1");
	}
	
    public static String transferToken(String token) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException{
    	Cipher cipher = Cipher.getInstance("AES");
	    cipher.init(Cipher.DECRYPT_MODE, SECRET_KEY);
	    byte[] newData = cipher.doFinal(token.getBytes("ISO-8859-1"));
	    String res = new String(newData);
		return res;
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/867032.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号