为了账号安全,请及时绑定邮箱和手机立即绑定

登录的演进

标签:
Java

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

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即可。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
1.6万
获赞与收藏
380

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

举报

0/150
提交
取消