app令牌的一个token实现

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     @Override
54     public String toString() {
55         return "Token [signature=" + signature + ", timestamp=" + timestamp
56                 + "]";
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: MD5
107      * @Description: 加密
108      * @param @param s
109      * @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 b
130      * @return
131      */
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: ListenToken
168      * @Description: 监听token过期线程runnable实现
169      * @author mrf
170      * @date 2015-10-21 下午02:22:24
171      *
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  

时间: 2024-11-05 18:48:54

app令牌的一个token实现的相关文章

App接口设计之token的php实现

为了保证移动端和服务端数据传输相对安全,需要对接口进行加密传输. 一.ttoken的设计目的:  因为APP端没有和PC端一样的session机制,所以无法判断用户是否登陆,以及无法保持用户状态,所以就需要一种机制来实现session,这就是token的作用 token是用户登陆的唯一票据,只要APP传来的token和服务器端一致,就能证明你已经登陆(就和你去看电影一样,需要买票,拿着票就能进了) 二.token设计时的种类: (1)第三方登陆型: 这种token形如微信的access_toke

如何用一个app操作另外一个app.比如微信群控那样的

如何实现一个app.控制另外的app,比如市面上群控微信的,是用测试工具的原理?还是什么模拟点击的原理? 如何用一个app操作另外一个app.比如微信群控那样的 >> android 这个答案描述的挺清楚的:http://www.goodpm.net/postreply/android/1010000007186891/如何用一个app操作另外一个app比如微信群控那样的.html

看我如何未授权登陆某APP任意用户(token泄露实例)

转载:https://www.nosafe.org/thread-333-1-1.html  先来看看这个.   首先,我在登陆时候截取返回包修改id值是无效的,因为有一个token验证,经过多次登陆发现,我自己的手机号对应的是一个token,这个token是不变的.所以脑海中就有了一个思路,只要能够获取到一个手机号,这个手机号对应的id和token值,替换进正确的返回包,说不定就能登陆上去.   也就是我们需要三个条件:   1.该用户的手机号   2.该用户账号的token   3.该用户账

5个小众且实用性超高的国产APP,每一个都是良心分享!

手机APP是大家都用用到的一些软件,而随着APP的快速兴起,越大越多的APP让人挑的眼花缭乱,因此,今天小编为大家分享5个小众且实用性超高的国产APP,每一个都是良心分享哦! 1.收趣:一款高效的阅读整理应用 --分类收藏:集中收藏,杜绝分散,一键即可分类全文搜索: --离线阅读:先收藏,后阅读: --语音播报:在线即可语音播报文章内容. 2. 一言:一款超级好用的记录收藏语句工具 --字句收藏:一款文字.一句话,总能够直击你的内心深处: --创作:你可以在里面分享一款你的感言,或许也能够引发别

android一个app打开另一个app的指定页面

一个app打开另一个app的指定页面方法 有以下几种 1.通过包名.类名 2.通过intent的 action 3.通过Url 方案1. ComponentName componentName = new ComponentName("com.example.bi", "com.example.bi.SplashActivity");//这里是 包名 以及 页面类的全称 Intent intent = new Intent(); intent.setComponen

ios上架app希望每一个技术能有更好的一份佣金 , 只要有心做你一定能做到更多

ios每个9000元起步而后每过一个+500封顶20000元一个,我们不做预付款,请在app通过审核之后联系我,IOS版本兼容8.0或以上 8.6或以上.我有需求你有技术, q 2305683978  ,D814619026   你可以跟谁都过不去但是你不能跟 money过不去吧

Android 一个app启动另一个app

[支付宝钱包],可以从支付宝直接跳转到[去啊],如果没有按照还提醒用户是否安装,有点炫酷哦,去啊的用户量一下增多了 第一个App中 // 通过包名获取要跳转的app,创建intent对象 Intent intent = activity().getPackageManager() .getLaunchIntentForPackage("com.zsl.download"); // 这里如果intent为空,就说名没有安装要跳转的应用嘛 if (intent != null) { //

Web API 身份验证 不记名令牌验证 Bearer Token Authentication

1. Startup.Auth.cs文件 添加属性 public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; } 添加静态构造函数 /// <summary> /// 构造函数 /// </summary> static Startup() { OAuthBearerOptions = new OAuthBearerAuthenticationOptions(); }

asp.net Web API 身份验证 不记名令牌验证 Bearer Token Authentication 简单实现

1. Startup.Auth.cs文件 添加属性 1 public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; } 添加静态构造函数 1 2 3 4 5 6 7 /// <summary> /// 构造函数 /// </summary> static Startup() {     OAuthBearerOptions = new OAuthBearerAuthent