几乎都是同事小哥哥帮我铺路,给我参考链接,实现的理论方法以及知识,我只剩下看资料,敲代码,出错了也是他帮我看着一步步解释搞定过来的。嗯,大好人一枚。
ok,思路:
是生成一个随机数放在url里面,当做参数传递,在业务请求controller那里检验这个nonce是否与缓存里的一致,并且添加一个时间戳的属性,这样可以设置一段时间内url有效,过段时间点击就出现链接失效的情况。
开始咯:
1:使用了SecureRandom生成随机数nonce
import java.security.SecureRandom; String nonce = null; SecureRandom random = null; try { random = SecureRandom.getInstance("SHA1PRNG"); System.out.println("SecureRandom random init:" + random); } catch (NoSuchAlgorithmException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } byte[] values = new byte[20]; random.nextBytes(values); nonce = String.valueOf(random.nextLong());
2 : 自定义一个class ,来构建一个对象,对象里面存放时间戳,nonce,openid.生成之后,把它放到一个cache里面,这个Guava Cache 存放。
假如只是简单的把Guava Cache当作HashMap或ConcurrentHashMap的替代品,不需要用到load方法,而是手动地插入,可以这样:
Java代码
public static final Cache<String, Object> cache = CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES).build();
注意不能用LoadingCache了。
查找:
cache.getIfPresent("xx");
插入:
cache.put("xx", "xxx");
3 : 获取缓存里面的数据去对比检验就好了
private Boolean checkTimeOut(String openid,String nonce){ Boolean flag = false; if(!nonce.isEmpty()){ StructureOfNonce v = (StructureOfNonce) MenuClickEventHandler.cache.getIfPresent(nonce); String cnonce = v.getNonce(); String copenid = v.getOpenid(); long createTimestamp = v.getTimestamp(); if(openid.equalsIgnoreCase(copenid) && nonce.equalsIgnoreCase(cnonce)){ Long currentTime = System.currentTimeMillis(); int time =(int) (currentTime - createTimestamp)/1000/60 ; if(0 <= time && time <= 1){ flag = true; } } } return flag; }
Cheers !
好的,全是别人的经验,下面放巨人的果实吧!
详细解析cacheGuava Cache :
http://bylijinnan.iteye.com/blog/2225074
CacheBuilder类的文档:
https://google.github.io/guava/releases/17.0/api/docs/com/google/common/cache/CacheBuilder.html
单例模式实现的范例,提供解题思路:
https://gxnotes.com/article/36005.html
生成随机数:
https://tersesystems.com/2015/12/17/the-right-way-to-use-securerandom/