Java Web防止用户重复登录(同一用户同时登录)的一种实现方案

1.思路

在Java web项目中,有时需要防止用户重复登录,解决方案有多种。比如Spring security就可以防止用户重复登录。 这里给出一个简单的解决方案:在处理登录的login方法中,先查询数据库验证下该用户是否存在,如果存在 判断该登录账户是否已经锁定了, 然后从application内置作用域对象中取出所有的登录信息,查看该username账户是否已经登录,如果登录了,就友好提示下,反之表示可以登录,将该登录信息以键值对的方式保存在application中。 当用户注销时,删除application中相关数据即可。

2.示例代码

2.1 处理登录方法

    @RequestMapping("/checkLogin.do")
    public String checkLogin(HttpSession session, String username, String password) {
        System.out.println("checkLogin.do");

        UserBean user=userService.login(username,password);
        if(user!=null){//登录成功

            //session.getServletContext()得到时application对象
            ServletContext application=session.getServletContext();
            Map<String, String> loginMap = (Map<String, String>)application.getAttribute("loginMap");
            if(loginMap==null){
                loginMap = new HashMap<>();
            }
            for(String key:loginMap.keySet()) {
                if (user.getUsername().equals(key)) {
                    if(session.getId().equals(loginMap.get(key))) {
                        System.out.println(username+"在同一地点多次登录!");
                    }else{
                        System.out.println(username+"异地登录被拒绝!");
                        session.setAttribute("tip", "该用户已经异地登录!");
                        return "forward:/index.jsp";
                    }
                }
            }
            loginMap.put(user.getUsername(),session.getId());
            application.setAttribute("loginMap", loginMap);
            session.setAttribute("username",user.getUsername());
            System.out.println("登录成功!");
            return "redirect:/index";
        }else{
            //登录失败
            System.out.println("登录失败!");
            session.setAttribute("tip","登录失败!");
            return "forward:/index.jsp";
        }
    }

2.2 销毁Session

package cn.hadron.servlet;

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import java.util.Map;

/**
 * Created by root on 17-9-28.
 */
public class SessionListener implements HttpSessionListener {

    @Override
    public void sessionCreated(HttpSessionEvent event) {

    }

    @Override
    public void sessionDestroyed(HttpSessionEvent event) {
        //在session销毁的时候 把loginMap中保存的键值对清除
        String username = event.getSession().getAttribute("username").toString();
        if(username!=null){
            Map<String, String> loginMap = (Map<String, String>)event.getSession().getServletContext().getAttribute("loginMap");
            loginMap.remove(username);
            event.getSession().getServletContext().setAttribute("loginMap",loginMap);
            System.out.println(username+"用户注销!");
        }
    }

}

2.3 web.xml

  <listener>
    <listener-class>cn.hadron.servlet.SessionListener</listener-class>
  </listener>

2.4 登录页面

${tip}
<form action="/user/checkLogin.do" method="post">
    帐号:<input type="text" name="username"><br>
    口令:<input type="password" name="password"><br>
    <input type="submit" value="登录">
</form>

3 测试

3.1 本地登录

注意:本地可以多次登录。

3.2 异地登录

另找一台机器测试

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Phoenix的Android之旅

如何监控app的崩溃

当我们的app上线到应用市场之后,它发生了什么崩溃其实我们是不知道的。今天我们介绍一个方法来监控和收集用户手机上的异常崩溃同时上报给我们自己。

592
来自专栏Android知识点总结

基于TCP的网络数据传输测试(使用腾讯云)

1112
来自专栏JavaEE

springboot整合shiro(含MD5加密)写在前面:开发环境:项目开始:

4K10
来自专栏我的小碗汤

Log4jConfigListener动态改变记录级别及实现

摘要: 线上的系统出现了bug,可能是请求的数据出现了问题,这个时候,日志就为我们提供了解决问题的办法。但是线上的产品系统,一般的优先级都在INFO之上,如果修...

954
来自专栏Java与Android技术栈

为爬虫框架构建Selenium模块、DSL模块(Kotlin实现)

NetDiscover是一款基于Vert.x、RxJava2实现的爬虫框架。我最近添加了两个模块:Selenium模块、DSL模块。

762
来自专栏小灰灰

spring-boot & ffmpeg 搭建一个音频转码服务

利用FFMPEG实现一个音频转码服务 提供一个音频转码服务,主要是利用ffmpeg实现转码,利用java web对外提供http服务接口 背景 音频转码服务...

8246
来自专栏Kirito的技术分享

JAVA拾遗--关于SPI机制

JDK提供的SPI(Service Provider Interface)机制,可能很多人不太熟悉,因为这个机制是针对厂商或者插件的,也可以在一些框架的扩展中看...

30411
来自专栏zhisheng

渣渣菜鸡的 ElasticSearch 源码解析 —— 启动流程(下)

上篇文章写完了 ES 流程启动的一部分,main 方法都入口,以及创建 Elasticsearch 运行的必须环境以及相关配置,接着就是创建该环境的节点了。

1063
来自专栏Spark学习技巧

写个yarn的监控

在星球里和微信群里很多朋友都有疑惑,如何监控 yarn 上 spark 或者 mr 应用的存活状态,浪尖今天在这里分享一下实现方法,实际上只需要简单的几行代码即...

813
来自专栏技术记录

前端插件——头像截图上传插件的使用(带后台)

效果图:实现上传头像,右边是预览,有三个大小,可以对头像进行裁剪 ? HTML: toParentData 和 img 返回的是图片裁剪后的base64编码。其...

5805

扫码关注云+社区