app令牌的一个token实现
来源:互联网 发布:mysql怎么设置两个主键 编辑:程序博客网 时间:2024/06/11 16:35
app登陆验证不能使用session来判断了。然后查资料都说用令牌,没找到合适的方法,我的眼界太小。另外,越来越感觉基础的重要,比如,session是什么,我竟无言以对。不知道session是什么,怎么来做验证呢。然后就关于类的加载和销毁,等。我需要重新看下java基础了。
这里,我定义了一个token类来存储token。就是一个字符串+创建的时间戳。然后定义一个管理类来维护token。简单的实现了,但还有很多问题。比如,我对session的理解(是否可以放session,放session之后什么状态),比如这定义的这个类在调用的时候加载,在不用的时间结束,而我希望一直存在,这个维护类怎么确保存在,这是类的声明周期问题,比如加载到内存和缓存的实现,缓存用的太少。
1.Token.java
1 package com.tixa.wedding.util; 2 3 import java.io.Serializable; 4 5 public class Token implements Serializable { 6 7 /** 8 * @Fields serialVersionUID : TODO 9 */ 10 private static final long serialVersionUID = -754659525548951914L;11 private String signature;12 private long timestamp;13 14 public Token(String signature, long timestamp) {15 if (signature == null)16 throw new IllegalArgumentException("signature can not be null");17 18 this.timestamp = timestamp;19 this.signature = signature;20 }21 22 public Token(String signature) {23 if (signature == null)24 throw new IllegalArgumentException("signature can not be null");25 26 this.signature = signature;27 }28 29 /**30 * Returns a string containing the unique signatureentifier assigned to this token.31 */32 public String getSignature() {33 return signature;34 }35 36 public long getTimestamp() {37 return timestamp;38 }39 40 /**41 * timestamp 不予考虑, 因为就算 timestamp 不同也认为是相同的 token.42 */43 public int hashCode() {44 return signature.hashCode();45 }46 47 public boolean equals(Object object) {48 if (object instanceof Token)49 return ((Token)object).signature.equals(this.signature);50 return false;51 }52 53 @Override54 public String toString() {55 return "Token [signature=" + signature + ", timestamp=" + timestamp56 + "]";57 }58 59 60 }
2.TokenUtil.java
1 package com.tixa.wedding.util; 2 3 import java.security.MessageDigest; 4 import java.util.Calendar; 5 import java.util.Date; 6 import java.util.HashMap; 7 import java.util.Map; 8 import java.util.Map.Entry; 9 import java.util.concurrent.Executors; 10 import java.util.concurrent.ScheduledExecutorService; 11 import java.util.concurrent.TimeUnit; 12 13 import org.apache.log4j.Logger; 14 15 16 17 public class TokenUtil { 18 19 private static final int INTERVAL = 7;// token过期时间间隔 天 20 private static final String YAN = "testMRf1$789787aadfjkds//*-+'[]jfeu;384785*^*&%^%$%";// 加盐 21 private static final int HOUR = 3;// 检查token过期线程执行时间 时 22 23 private static Logger logger = Logger.getLogger("visit"); 24 25 private static Map<Integer, Token> tokenMap = new HashMap<Integer, Token>(); 26 private static TokenUtil tokenUtil = null; 27 static ScheduledExecutorService scheduler =Executors.newSingleThreadScheduledExecutor(); 28 29 static { 30 logger.info("\n===============进入TokenUtil静态代码块=================="); 31 listenTask(); 32 } 33 34 35 public static TokenUtil getTokenUtil() { 36 if (tokenUtil == null) { 37 synInit(); 38 } 39 40 return tokenUtil; 41 } 42 43 private static synchronized void synInit() { 44 if (tokenUtil == null) { 45 tokenUtil = new TokenUtil(); 46 } 47 } 48 49 public TokenUtil() { 50 } 51 52 53 54 public static Map<Integer, Token> getTokenMap() { 55 return tokenMap; 56 } 57 58 /** 59 * 产生一个token 60 */ 61 public static Token generateToken(String uniq,int id) { 62 Token token = new Token(MD5(System.currentTimeMillis()+YAN+uniq+id), System.currentTimeMillis()); 63 synchronized (tokenMap) { 64 tokenMap.put(id, token); 65 } 66 return token; 67 } 68 69 70 /** 71 * @Title: removeToken 72 * @Description: 去除token 73 * @param @param nonce 74 * @param @return 参数 75 * @return boolean 返回类型 76 */ 77 public static boolean removeToken(int id) { 78 synchronized (tokenMap) { 79 tokenMap.remove(id); 80 logger.info(tokenMap.get(id) == null ? "\n=========已注销========": "\n++++++++注销失败+++++++++++++++"); 81 } 82 return true; 83 } 84 85 /** 86 * @Title: volidateToken 87 * @Description: 校验token 88 * @param @param signature 89 * @param @param nonce 90 * @param @return 参数 91 * @return boolean 返回类型 92 */ 93 public static boolean volidateToken(String signature, int id) { 94 boolean flag = false; 95 Token token = (Token) tokenMap.get(id); 96 if (token != null && token.getSignature().equals(signature)) { 97 logger.info("\n=====已在线======="); 98 flag = true; 99 }100 101 return flag;102 }103 104 /**105 * 106 * @Title: MD5107 * @Description: 加密108 * @param @param s109 * @param @return 参数110 * @return String 返回类型111 */112 public final static String MD5(String s) {113 try {114 byte[] btInput = s.getBytes();115 // 获得MD5摘要算法的 MessageDigest 对象116 MessageDigest mdInst = MessageDigest.getInstance("MD5");117 // 使用指定的字节更新摘要118 mdInst.update(btInput);119 // 获得密文120 return byte2hex(mdInst.digest());121 } catch (Exception e) {122 e.printStackTrace();123 return null;124 }125 }126 127 /**128 * 将字节数组转换成16进制字符串129 * @param b130 * @return131 */132 private static String byte2hex(byte[] b) {133 StringBuilder sbDes = new StringBuilder();134 String tmp = null;135 for (int i = 0; i < b.length; i++) {136 tmp = (Integer.toHexString(b[i] & 0xFF));137 if (tmp.length() == 1) {138 sbDes.append("0");139 }140 sbDes.append(tmp);141 }142 return sbDes.toString();143 }144 145 /**146 * @Title: listenTask 147 * @Description: 定时执行token过期清除任务148 * @param 参数149 * @return void 返回类型150 */151 public static void listenTask(){152 Calendar calendar = Calendar.getInstance();153 int year = calendar.get(Calendar.YEAR);154 int month = calendar.get(Calendar.MONTH);155 int day = calendar.get(Calendar.DAY_OF_MONTH);156 //定制每天的HOUR点,从明天开始157 calendar.set(year, month, day+1, HOUR, 0, 0);158 // calendar.set(year, month, day, 17, 11, 40);159 Date date = calendar.getTime();160 161 scheduler.scheduleAtFixedRate( new ListenToken(), (date.getTime()-System.currentTimeMillis())/1000, 60*60*24, TimeUnit.SECONDS);162 }163 164 165 166 /**167 * @ClassName: ListenToken168 * @Description: 监听token过期线程runnable实现169 * @author mrf170 * @date 2015-10-21 下午02:22:24171 * 172 */173 static class ListenToken implements Runnable {174 public ListenToken() {175 super();176 }177 178 public void run() {179 logger.info("\n**************************执行监听token列表****************************");180 try {181 synchronized (tokenMap) {182 for (int i = 0; i < 5; i++) {183 if (tokenMap != null && !tokenMap.isEmpty()) {184 for (Entry<Integer, Token> entry : tokenMap.entrySet()) {185 Token token = (Token) entry.getValue();186 logger.info("\n==============已登录用户有:"+entry + "=====================");187 // try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}188 int interval = (int) ((System.currentTimeMillis() - token.getTimestamp()) / 1000 / 60 / 60 / 24);189 if (interval > INTERVAL) {190 tokenMap.remove(entry.getKey());191 logger.info("\n==============移除token:" + entry+ "=====================");192 }193 194 }195 }196 }197 198 }199 } catch (Exception e) {200 logger.error("token监听线程错误:"+e.getMessage());201 e.printStackTrace();202 }203 }204 }205 206 207 208 public static void main(String[] args) {209 System.out.println(generateToken( "s",1));210 System.out.println(generateToken( "q",1));211 System.out.println(generateToken( "s3",2));212 System.out.println(generateToken( "s4",3));213 System.out.println(removeToken(3));214 System.out.println(getTokenMap());215 }216 217 }218 219
0 0
- app令牌的一个token实现
- 生成一个固定长度的令牌token
- Token 令牌自实现
- jBPM的token(令牌)
- Token 令牌
- TOKEN令牌
- Access Token访问令牌的操作
- Struts的Token(令牌)机制
- struts2中token的令牌机制
- rest token的一个实现
- 简单实现Shiro单点登录(自定义Token令牌)
- 简单实现Shiro单点登录(自定义Token令牌)
- 简单实现Shiro单点登录(自定义Token令牌)
- 简单实现Shiro单点登录(自定义Token令牌)
- PHP Token(令牌)设计
- 进程令牌(TOKEN)相关!
- 令牌环(Token Ring)
- struts中的令牌token
- velocity分页模板
- 初学mysql(一)-数据库和表的操作
- C++之RAII惯用法
- Xcode8打包APP上传到APPStore遇到的问题
- Cannot read property ‘msie’ of undefined
- app令牌的一个token实现
- 从国家统计局爬下来的地区信息
- 字符串分割的两种方法
- 省市县三级联动
- dom4j的读写xml文件,读写xml字符串
- java日志组件介绍(common-logging,log4j,slf4j,logback )
- 简单的使用ehcache
- 洛谷 P1016 旅行家的预算
- java反射实现动态代理