用户唯一登录,最新登录挤掉以前的登录,实现踢人.

最近在做一个功能,要求是这样的:相同的账号,例如admin账号,在A电脑登录成功,然后admin账号在B电脑登录,系统发现admin账号出现了重复登录,A电脑上登录的admin账号就会被退出登录。

流程图:

我的具体实现方式如下:

1、admin账号在A电脑登录某系统,在登录成功之前,查询redis是否存在登录信息,登录信息结构为:key=用户名,value=sessionid,如果存在,用map集合存起来,如果不存在,则往redis存入登录信息,数据结构是:key=用户名,value=sessionid。

2、把sessionid存入cookie中,不设置过期时间,浏览器关闭则失效

3、如果登录不成功,比如密码错误,则把存在redis中的登录信息删除,如果之前就有存在登录信息,则需要还原信息,从第1步中的map中取出临时存储的登录信息还原到redis上。

4、系统检测admin账号是否重复登录,可以使用拦截器,拦截除了登录请求之外的所有请求,判断admin账号是否已经在其他地方登录,如果是,则马上退出登录。如何判断admin账号是否已经在其他地方登录?实现思路:

①、拦截器方法中获取到sessionid,通过账号名获取到redis上面的sessionid;

②、对比两个sessionid,如果不相等,则说明admin账号在其他地方登录了,当前登录即刻退出登录。

5、使用浏览器的sessionid作为判断标准,那么就是同一台电脑里不同浏览器的sessionid就会不一致,意思就是admin账号不能再多个浏览器登录了。

6、session的默认过期时间是30分钟,在springboot的项目中如何设置session的存活时间呢?可以在配置文件中设置,也可以在启动类中加上一下一段代码即可:

//设置session过期时间
@Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {
    return new EmbeddedServletContainerCustomizer() {
        @Override
        public void customize(ConfigurableEmbeddedServletContainer container) {
            container.setSessionTimeout(10800);// 单位为S
        }
    };
}

7、我做的项目是springboot+springcloud的系统,有多个模块,就有多个启动tomcat,那么在浏览器在访问A模块的时候得到的sessionid和浏览器访问B模块的时候获取到的sessionid是不一样的。加入登录功能在A模块中,那么redis上的sessionid就是对应A模块服务器的。这就导致了B模块拿到的sessionid和redis上的sessionid不一致,这就导致了不管admin账号是否有重复登录,用户访问B模块的时候,都会退出登录。如何解决这个问题?思路如下:

①、由于系统是在同一个浏览器上面打开的,模块集成在同一个主页中,登录的时候,把在对应A模块的sessionid存在cookie里。

②、其他模块就从cookie里面获取sessionid,就可以实现多个模块使用同一个sessionid了。

8、其实按照第7点那样的做法是有点麻烦了,可以用网关实现拦截器,这样的话就可以不管什么模块,所有的请求都经过拦截器,就可以完美解决问题了,我为什么不这样做?是因为我们系统没有网关,这个后续应该会改进。

思路就是这样,亲测可以达到想要的效果,希望能帮助你们。如果你们有什么更好的建议,欢迎留言赐教。

猜你喜欢

转载自blog.csdn.net/BelleHarvester/article/details/88299000
今日推荐