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