java token生成和校验的一个案例

现在越来越多的登录方式都用到了token作为用户登录令牌,所以实现了一个token生成和校验案例。

缺点:该实现方式token是存储在内存中,不适合分布式项目,如需改为分布式项目部署,可把token存储在redis中,其中的实现原理还是保持不变。

一)token编码工具类

package com.oysept.token.utils;

/**
 * token编码工具类
 * @author ouyangjun
 */
public class TokenEncryptUtils {
	
	// 编码密码,可自定义
	private static final String ENCODED_PASSWORD = "ouyangjun";
	
	/**
	 * 编码
	 * @param str
	 * @return
	 */
	public static String encoded(String str) {
		return strToHex(encodedString(str, ENCODED_PASSWORD));
	}
	
	/**
	 * 转换
	 * @param str
	 * @param password
	 * @return
	 */
	private static String encodedString(String str, String password) {
		char[] pwd = password.toCharArray();
		int pwdLen = pwd.length;
		
        char[] strArray = str.toCharArray();
        for (int i=0; i

二)token生成和校验工具类(包含main方法测试)

package com.oysept.token.utils;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

/**
 * token生成和校验
 * @author ouyangjun
 */
public class TokenUtils {

	private static Map MAP_TOKENS = new HashMap();
	private static final int VALID_TIME = 60*60*2; // token有效期(秒)
	public static final String TOKEN_ERROR = "F"; // 非法
	public static final String TOKEN_OVERDUE = "G"; // 过期
	public static final String TOKEN_FAILURE = "S"; // 失效
	
	/**
	 * 生成token,该token长度不一致,如需一致,可自行MD5或者其它方式加密一下
	 * 该方式的token只存在磁盘上,如果项目是分布式,最好用redis存储
	 * @param str: 该字符串可自定义,在校验token时要保持一致
	 * @return
	 */
	public static String getToken(String str) {
		String token = TokenEncryptUtils.encoded(getCurrentTime()+","+str);
		MAP_TOKENS.put(str, token);
		return token;
	}
	
	/**
	 * 校验token的有效性
	 * @param token
	 * @return
	 */
	public static String checkToken(String token) {
		if (token == null) {
			return TOKEN_ERROR;
		}
		try{
			String[] tArr = TokenEncryptUtils.decoded(token).split(",");
			if (tArr.length != 2) {
				return TOKEN_ERROR;
			}
			// token生成时间戳
			int tokenTime = Integer.parseInt(tArr[0]);
			// 当前时间戳
			int currentTime = getCurrentTime();
			if (currentTime-tokenTime < VALID_TIME) {
				String tokenStr = tArr[1];
				String mToken = MAP_TOKENS.get(tokenStr);
				if (mToken == null) {
					return TOKEN_OVERDUE;
				} else if(!mToken.equals(token)) {
					return TOKEN_FAILURE;
				}
				return tokenStr;
			} else {
				return TOKEN_OVERDUE;
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
		return TOKEN_ERROR;
	}
	
	/**获取当前时间戳(10位整数)*/
	public static int getCurrentTime() {
		return (int)(System.currentTimeMillis()/1000);
	}
	
	/**
	 * 移除过期的token
	 */
	public static void removeInvalidToken() {
		int currentTime = getCurrentTime();
		for (Entry entry : MAP_TOKENS.entrySet()) {
			String[] tArr = TokenEncryptUtils.decoded(entry.getValue()).split(",");
			int tokenTime = Integer.parseInt(tArr[0]);
			if(currentTime-tokenTime > VALID_TIME){
				MAP_TOKENS.remove(entry.getKey());
			}
		}
	}
	
	/**
	 * 测试
	 * @param args
	 */
	public static void main(String[] args) {
		String str = "username_and_password";
		
		// 获取token
		String token = TokenUtils.getToken(str);
		System.out.println("token Result: " + token);
		
		// 校验token
		String checkToken = TokenUtils.checkToken(token);
		System.out.println("checkToken Result: " + checkToken);
		if(str.equals(checkToken)) {
			System.out.println("==>token verification succeeded!");
		}
		
	}
	
}

本章完结,待续!

 

本文说明:该文章属于原创,如需转载,请标明文章转载来源

你可能感兴趣的:(Java随作)