app登陸驗(yàn)證不能使用session來判斷了。然后查資料都說用令牌,沒找到合適的方法,我的眼界太小。另外,越來越感覺基礎(chǔ)的重要,比如,session是什么,我竟無言以對(duì)。不知道session是什么,怎么來做驗(yàn)證呢。然后就關(guān)于類的加載和銷毀,等。我需要重新看下java基礎(chǔ)了。
這里,我定義了一個(gè)token類來存儲(chǔ)token。就是一個(gè)字符串+創(chuàng)建的時(shí)間戳。然后定義一個(gè)管理類來維護(hù)token。簡(jiǎn)單的實(shí)現(xiàn)了,但還有很多問題。比如,我對(duì)session的理解(是否可以放session,放session之后什么狀態(tài)),比如這定義的這個(gè)類在調(diào)用的時(shí)候加載,在不用的時(shí)間結(jié)束,而我希望一直存在,這個(gè)維護(hù)類怎么確保存在,這是類的聲明周期問題,比如加載到內(nèi)存和緩存的實(shí)現(xiàn),緩存用的太少。
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 不予考慮, 因?yàn)榫退?timestamp 不同也認(rèn)為是相同的 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過期時(shí)間間隔 天 20 private static final String YAN = "testMRf1$789787aadfjkds//*-+'[]jfeu;384785*^*&%^%$%";// 加鹽 21 private static final int HOUR = 3;// 檢查token過期線程執(zhí)行時(shí)間 時(shí) 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===============進(jìn)入TokenUtil靜態(tài)代碼塊=================="); 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 * 產(chǎn)生一個(gè)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 參數(shù) 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: 校驗(yàn)token 88 * @param @param signature 89 * @param @param nonce 90 * @param @return 參數(shù) 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 參數(shù)110 * @return String 返回類型111 */112 public final static String MD5(String s) {113 try {114 byte[] btInput = s.getBytes();115 // 獲得MD5摘要算法的 MessageDigest 對(duì)象116 MessageDigest mdInst = MessageDigest.getInstance("MD5");117 // 使用指定的字節(jié)更新摘要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 * 將字節(jié)數(shù)組轉(zhuǎn)換成16進(jìn)制字符串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: 定時(shí)執(zhí)行token過期清除任務(wù)148 * @param 參數(shù)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點(diǎn),從明天開始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: 監(jiān)聽token過期線程runnable實(shí)現(xiàn)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**************************執(zhí)行監(jiā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監(jiān)聽線程錯(cuò)誤:"+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
聯(lián)系客服