登录的演进

随着技术的迭代和变更,登录模块的也有了很多的变化,今天就主要来说说这个问题。

javaweb

javaweb时代是学校教学的一部分,他是使用了servlet来进行编程,有的教学会使用一些框架,例如springmvc。里面的登录案例都是使用session来做的。第一次登录做检验,如果成功,就把登录信息放在session里。而且session有超时时间控制,可以在对长期不访问的会剔除数据。session可以说是完美支持登录。
session是按照浏览器来作为唯一标识的,每次浏览器访问都会带着jssesionid,以此作为找到具体session的标志。

分布式

在单机不满足的时候,分布式出场了,开始有负载均衡的事情了,由于多个jvm一起协作了,session还是保持在单个jvm的,这个就没法用了,于是有了redis这种分布式缓存,也有ttl来控制时间。与浏览器交互的也就变成了token。没办法使用jsessionid了。于是服务端需要生成token,每次访问都带着这个token。

前后台分离

大型的项目前后台分离完全可以使用分布式的做法,但是也有小型的项目,尤其是使用springboot的时候,大家经常会遇到一个问题,就是使用session生成的id特别慢,会出现如下的日志。

Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [140,108] milliseconds.

网上可以查到解决方案。这里不做讨论。这是一个session的问题,那是否可以不用session呢,例如分布式的那种方案,不过为此加一个redis组建是很麻烦的事情,不如自己写一个简单满足需求的情况。 主要满足2个需求,一个是可以根据key找到value,第二个是要时间的过期限制。

public class LocalCache implements Runnable {


    private static ScheduledExecutorService swapExpiredPool
            = new ScheduledThreadPoolExecutor(1);
    {
        swapExpiredPool.scheduleWithFixedDelay(new LocalCache(), 5, 5, TimeUnit.MINUTES);
    }

    public static final long TIME = 30 * 60 * 1000;

    private static class DataInfo {
        public String value;
        public long currentTime;

        public DataInfo(String value, long currentTime) {
            this.value = value;
            this.currentTime = currentTime;
        }
    }

    public static ConcurrentHashMap<String, DataInfo> hashMap = new ConcurrentHashMap<>();

    public static void put(String key, String value) {
        hashMap.put(key, new DataInfo(value, System.currentTimeMillis()));
    }

    public static String get(String key) {
        DataInfo dataInfo = hashMap.get(key);
        dataInfo.currentTime = System.currentTimeMillis();
        return dataInfo.value;
    }

    @Override
    public void run() {
        long currentTime = System.currentTimeMillis();
        Set<Map.Entry<String, DataInfo>> entries = hashMap.entrySet();
        Iterator<Map.Entry<String, DataInfo>> iterator = entries.iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, DataInfo> next = iterator.next();
            long time = next.getValue().currentTime;
            if (currentTime - time > TIME) {
                iterator.remove();
            }
        }
    }
}

我们用ConcurrentHashMap来做数据的保存,并且启动定时任务,每5分钟进行一次过期清理。只要找一个唯一id生成器就好。做为我们的key。每次只要把依旧传递token即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值