web应用中实现同一个账号,后面登录的会把前面登录的挤下线

  在web应用中假如没有做会话控制,会出现这样的情况,A登录了账号,B也登录了账号,都是同样的账号,A修改了信息,B会看到修改的信息,这样的用户体验不好,B会觉得我没有修改啊,为什么信息会改变。而做会话控制后,A先登录,B再登录,那么B会把A的登录挤下线。

  实现思路:采用时间戳比较

  1首先用户登录时,后台是不需要做拦截的,前台把用户名和密码传到后台,后台生成JWT格式的token给前台,并以token为key,用户信息为value存入redis中

  2其他url路径,过滤器会拦截请求,先判断前台是否携带了token,或者是携带了token,但是已经失效了(redis中查不到)会直接返回前台错误信息,这时候会以用户名为key,从redis中查询token,没有就以key为用户名,value为token存入redis.放行请求,若从redis查询的token和从前台传进来的token相同,放行请求,若从redis查询的token和从前台传进来的token不相同,如果从前台传递的token的时间戳大于redis中的,则覆盖redis中的token,否认注销token,返回您的账号已经在其他设备登录,拦截请求。

public class CompareKickOutFilter extends KickOutFilter {
    @Override
    public boolean isAccessAllowed(HttpServletRequest request, HttpServletResponse response) {
        String token = request.getHeader("Authorization");
        String username = JWTUtil.getUsername(token);
        String userKey = PREFIX + username;
        RBucket<String> bucket = redissonClient.getBucket(userKey);
        String redisToken = bucket.get();

        if (StringUtils.isBlank(redisToken)) {// 第一次设置
            bucket.set(token);
        } else if (token.equals(redisToken)) { // 相同的token
            return true;
        } else {
            Long redisTokenUnixTime = JWTUtil.getClaim(redisToken, "createTime").asLong();
            Long tokenUnixTime = JWTUtil.getClaim(token, "createTime").asLong();
            if (tokenUnixTime.compareTo(redisTokenUnixTime) > 0) {
                // 传进来的token是离现在最新的,覆盖旧的token
                bucket.set(token);
            } else {
                // 注销当前token
                userService.logout(token);
                sendJsonResponse(response, 4001, "您的账号已在其他设备登录");
                return false;
            }
        }
        return true;
    }
}

项目结构:

项目地址:https://github.com/jake1263/loginCtl

原文地址:https://www.cnblogs.com/moris5013/p/11128135.html

时间: 2024-11-08 22:10:00

web应用中实现同一个账号,后面登录的会把前面登录的挤下线的相关文章

数字证书在WEB应用中登录

1数字证书登录认证的优点 作为企业信息系统的第一道大门,身份认证是确保企业信息资源只能被合法用户所访问的重要保障. 传统的口令认证方式虽然简单,但是由于其易受到窃听.重放等攻击的安全缺陷,使其已无法满足当前复杂网络环境下的安全认证需求. 传统账号+口令登录的弊端: 1.         口令易被猜测.由于有的用户为了方便记忆,使用非常简单的口令,比如"1234"."abcd"等这些非常容易被猜测的口令. 2.         口令易被窃听.大家都知道,WEB应用在互

php 实现同一个账号同时只能一个人登录

php 实现同一个账号同时只能一个人登录 张映 发表于 2015-01-22 分类目录: php 以前考虑过这个问题,今天实现了一下,挺快的,从研究到开发完成差不多4个小时.有点类似QQ,二台电脑登录,一台会把另一台挤掉线,并提示其他地点登录信息. 一,实现原理 1,用户在电脑A登录,session信息存放在redis当中,并将session_id存到mysql数据库中. 2,同一用户在电脑B登录,验证完用户名和密码后,将该用户信息从数据库读出,取得用户在电脑A登录的session_id,然后在

设置在 Ubuntu 12.04 中使用root 账号进行登录与修改 Linux 系统中的计算机名

3.设置在 Ubuntu 12.04 中使用root 账号进行登录 1.先设定一个 root 的密码,sudo passwd root 2.root 登录,su root 3.备份一下 lightgdm cp -p /etc/lightdm/lightdm.conf /etc/lightdm/lightdm.conf.bak 4.编辑 lightdm.conf sudo gedit /etc/lightdm/lightdm.conf 5.加: greeter-show-manual-login=

因为此控件已在 web.config 中注册并且与该页位于同一个目录中

在web.config文件配置了用户控件 <pages> <controls> <add tagPrefix="my" tagName="login" src="~/login.ascx" /> </controls> </pages> 然后在aspx页面引用该控件 <my:login runat="sever" id="myLogin" /

【初码干货】使用阿里云对Web开发中的资源文件进行CDN加速的深入研究和实践

提示:阅读本文需提前了解的相关知识 1.阿里云(https://www.aliyun.com) 2.阿里云CDN(https://www.aliyun.com/product/cdn) 3.阿里云OSS(https://www.aliyun.com/product/oss) 4.HTTPS(http://baike.baidu.com/view/14121.htm) 阅读目录结构 引: 一.准备工作 二.整体功能结构 三.具体实现步骤 四.关键点和问题处理 五.延伸与扩展 六.总结与思考 引:

高访问量WEB开发中的架构模式,学习从点滴开始

当一个Web系统从日访问量10万逐步增长到1000万,甚至超过1亿的过程中,Web系统承受的压力会越来越大,在这个过程中,我们会遇到很多的问题.为了解决这些性能压力带来问题,我们需要在Web系统架构层面搭建多个层次的缓存机制.在不同的压力阶段,我们会遇到不同的问题,通过搭建不同的服务和架构来解决. Web负载均衡 Web负载均衡(Load Balancing),简单地说就是给我们的服务器集群分配"工作任务",而采用恰当的分配方式,对于保护处于后端的Web服务器来说,非常重要. 负载均衡

在 Web 项目中应用 Apache Shiro

Apache Shiro 是功能强大并且容易集成的开源权限框架,它能够完成认证.授权.加密.会话管理等功能.认证和授权为权限控制的核心,简单来说,"认证"就是证明你是谁? Web 应用程序一般做法通过表单提交用户名及密码达到认证目的."授权"即是否允许已认证用户访问受保护资源.关于 Shiro 的一系列特征及优点,很多文章已有列举,这里不再逐一赘述,本文重点介绍 Shiro 在 Web Application 中如何实现验证码认证以及如何实现单点登录. 用户权限模型

web.xml中Filter,Listener,Servlet的区别

一.Servlet Servlet是基本的服务端程序,他来自接口Servlet,接口中有方法service.而Servlet的一个重要实现类,则是tomcat服务器的核心,那就是HttpServlet HttpServlet有方法: public abstract class HttpServlet extends GenericServlet { private static final String METHOD_DELETE = "DELETE"; private static

web过滤器中获取请求的参数(content-type:multipart/form-data)

1.前言: 1.1 在使用springMVC中,需要在过滤器中获取请求中的参数token,根据token判断请求是否合法: 1.2 通过requst.getParameter(key)方法获得参数值; 这种方法有缺陷:它只能获取  POST 提交方式中的Content-Type: application/x-www-form-urlencoded; HttpServletRequest request= (HttpServletRequest) req; String param = reque