文章目录

  • 1. html 部分
  • 2. js部分
  • 3. 拦截器部分
  • 4. 认证授权部分
  • 5. 控制层部分
  • 6. 工具类

实现流程:
1.从reqest域中获取现在登陆的新sessionId
2.根据登陆的用户名从reqest域中获取已经登陆的老sessionId
3.判断老sessionId是否存在和新旧sessionId是否是否一致
如果一直返回当前用户和当前用户已经登陆的ip地址
前台根据返回的结果页面弹框提示

1. html 部分
 <form id="formId" class="layui-form" action="${ctxPath}/login" method="post"><!-- 用户名 --><div class="layui-form-item"><div class="layui-input-block"><img src="${ctxPath}/assets/common/img/user.png"><input id="username" type="text" name="username" id="username" requiredlay-verify="required" placeholder="输入用户名" autocomplete="off" class="layui-input"></div></div><!-- 密码 --><div class="layui-form-item"><div class="layui-input-block"><img src="${ctxPath}/assets/common/img/password.png"><input type="password" name="password" id="password" required lay-verify="required"placeholder="输入密码" autocomplete="off" class="layui-input"></div></div><!-- 记住密码 --><div class="layui-form-item"><label class="layui-form-label" lay-tips="7天内免登陆"style="width:60px !important;padding:9px 0;margin-right:20px">记住密码</label><div class="layui-input-block"><input class="radio" type="radio" name="remember" value="on" title="是"><input type="radio" name="remember" value="off" title="否" checked=""></div></div><!-- 登录按钮  --><div class="layui-form-item"><button lay-filter="login-submit" id="submit" class="layui-btn layui-btn-primary loginBtn"lay-submit>登录</button></div></form>
2. js部分
<script>layui.use(['layer', 'form'], function () {var $ = layui.jquery;var layer = layui.layer;var form = layui.form;$("#submit").click(function () {$.ajax({url: "/checkLogin",type: 'POST',dataType: 'json',data: {username: $("#username").val()},async: false,success: function (msg) {var ip = msg.data.ip;if (ip != '') {if (window.confirm("用户'" + $('#username').val() + "'已在" + ip + "登陆,是否在本电脑登陆?")) {falg = true;} else {falg = false;}}$('#formId').submit();}});return falg;});var errorMsg = "${tips!}";if (errorMsg) {layer.msg(errorMsg, {icon: 5, anim: 6});}});
</script>
3. 拦截器部分
package com.gblfy.controller;import cn.stylefeng.roses.core.reqres.response.ResponseData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;/*** 登陆前校验** @author guobin* @date 2021-01-27*/
@Controller
public class CheckLogInController {private final static Logger logger = LoggerFactory.getLogger(CheckLogInController.class);@RequestMapping(value = "/checkLogin", method = RequestMethod.POST)@ResponseBodypublic ResponseData CheckLogin(HttpServletRequest request, HttpServletResponse httpServletResponse) {//        Boolean flag = false;//true-已经登陆 false-未登陆或登陆session一样String ip = "";//返回空-未登录。非空-已登录Map<String, Object> mmap = new HashMap<>();try {//获取当前用户的sessionIdString sessionId = request.getSession().getId();//当前sessionidString username = request.getParameter("username").trim();//用户名String sessionIdOld = (String) request.getServletContext().getAttribute(username);//老sessionId//如果老sessionId不为null 且新老sessionId不一致,则当前账号已有人登陆mmap.put("ip",ip);if (null != sessionIdOld && !"".equals(sessionId) && !sessionId.equals(sessionIdOld)) {ip = (String) request.getServletContext().getAttribute(username + "IP");mmap.put("ip",ip);}} catch (Exception e) {logger.error("从session中获取用户登陆ip失败:", e);ip = "";}return ResponseData.success(mmap);}
}
4. 认证授权部分
/*** 不需要权限验证的资源表达式*/List<String> NONE_PERMISSION_RES = CollectionUtil.newLinkedList("/assets/**","/checkLogin","/login", "/global/sessionError", "/kaptcha", "/error", "/global/error");
5. 控制层部分
/*** 点击登录执行的动作** @author gblfy* @Date 2019/11/23 5:42 PM*/@RequestMapping(value = "/login", method = RequestMethod.POST)public String loginVali(HttpServletRequest request) {String sessionId = request.getSession().getId();String username = super.getPara("username").trim();String password = super.getPara("password").trim();//如果开启了记住我功能String remember = super.getPara("remember");Subject currentUser = ShiroKit.getSubject();UsernamePasswordToken token = new UsernamePasswordToken(username, password.toCharArray());//如果开启了记住我功能if ("on".equals(remember)) {token.setRememberMe(true);} else {token.setRememberMe(false);}//执行shiro登录操作currentUser.login(token);//登录成功,记录登录日志ShiroUser shiroUser = ShiroKit.getUserNotNull();super.getSession().setAttribute("shiroUser", shiroUser);super.getSession().setAttribute("username", shiroUser.getAccount());try {//获取老sessionIdString sessionIdOld = (String) request.getServletContext().getAttribute(username);if (null != sessionIdOld && !sessionId.equals(sessionIdOld)) {//注销老sessionHttpSession session = (HttpSession) request.getServletContext().getAttribute(sessionIdOld);session.invalidate();}//获取老sessionId} catch (Exception e) {e.printStackTrace();//非正常清空session}//重新赋值
request.getSession().getServletContext().setAttribute(username, sessionId);request.getSession().getServletContext().setAttribute(sessionId, request.getSession());request.getSession().getServletContext().setAttribute(username + "IP", Inet4AddresslUtils.getReqIp(request));LogManager.me().executeLog(LogTaskFactory.loginLog(shiroUser.getId(), getIp()));ShiroKit.getSession().setAttribute("sessionFlag", true);return REDIRECT + "/";}
6. 工具类
package com.gblfy.controller;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import javax.servlet.http.HttpServletRequest;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;public class Inet4AddresslUtils {private final static Logger logger = LoggerFactory.getLogger(Inet4AddresslUtils.class);/*** 获取请求主机的ip地址** @param request* @return*/public static String getReqIp(HttpServletRequest request) {String ip = request.getHeader("x-forwarded-for");if ((ip == null) || (ip.length() == 0) || ("unknown".equalsIgnoreCase(ip))) {ip = request.getHeader("Proxy-Client-IP");}if ((ip == null) || (ip.length() == 0) || ("unknown".equalsIgnoreCase(ip))) {ip = request.getHeader("WL-Proxy-Client-IP");}if ((ip == null) || (ip.length() == 0) || ("unknown".equalsIgnoreCase(ip))) {ip = request.getRemoteAddr();}return ip;}/*** 获取服务器本机的ip地址** @return*/public static String getInet4Address() {Enumeration<NetworkInterface> nis;String ip = null;try {nis = NetworkInterface.getNetworkInterfaces();for (; nis.hasMoreElements(); ) {NetworkInterface ni = nis.nextElement();Enumeration<InetAddress> ias = ni.getInetAddresses();for (; ias.hasMoreElements(); ) {InetAddress ia = ias.nextElement();if (ia instanceof Inet4Address && !ia.getHostAddress().equals("127.0.0.1")) {ip = ia.getHostAddress();}}}} catch (SocketException e) {logger.error("获取ip地址异常", e);}return ip;}
}

限制在同一台电脑上只允许有一个用户登录相关推荐

  1. 限制在同一台电脑上只允许有一个用户登录系统

    在web应用系统中,出于安全性考虑,经常需要对同一客户端登录的用户数量和一个客户同时在多个客户端登陆进行限制. 具体一点就是: 1.在同一台电脑上一次只允许有一个用户登录系统: 2.一个用户在同一时间 ...

  2. java限制在同一台电脑上只允许有一个用户登录系统

    在web应用系统中,出于安全性考虑,经常需要对同一客户端登录的用户数量和一个客户同时在多个客户端登陆进行限制. 具体一点就是: 1.在同一台电脑上一次只允许有一个用户登录系统: 2.一个用户在同一时间 ...

  3. 软件双开限定-一台电脑上只允许开一个软件

    只要是创建进程互斥锁 //** 软件双开限定HANDLE hMutex = CreateMutex(NULL, false, "Process");if(GetLastError( ...

  4. 在一台电脑上使用两个github账号

    问题描述: 我公司有一个github账号,每天工作把代码传上去,我觉得代码写的好,我同时想上传到自己的github账号上面去,但是目前只有一台电脑,如何在一台电脑上面进行设置,使这一台电脑可以同时上传 ...

  5. 在同一台电脑上同时安装Python2和Python3

    目前Python的两个版本Python2和Python3同时存在,且这两个版本同时在更新与维护. 到底是选择Python2还是选择Python3,取决于当前要使用的库.框架支持哪个版本. 例如:HTM ...

  6. 两个计算机系统安装,如何在一台电脑上同时重装两个系统|戴尔电脑怎么安装两个系统...

    有些用户,想用win10的同时,又想用win7,所以需要安装双系统.这篇文章就是白云一键重装系统给这类用户带来的方法教程,其实原理很简单,同一块硬盘,可以分成多个分区,然后再在上面分别安装系统即可. ...

  7. 电脑同时安装python2和3_一台电脑上同时安装python2和python3

    被python2的编码问题整的快晕了,python3对编码问题解决的不错 所以想安装下python3,但由于目前企业大多还是用python2,所以不想卸载2,让python2和python3共存. 本 ...

  8. 电脑可以同时装python2和3吗_在同一台电脑上同时安装Python2和Python3-Go语言中文社区...

    在同一台电脑上同时安装Python2和Python3 目前Python的两个版本Python2和Python3同时存在,且这两个版本同时在更新与维护. 到底是选择Python2还是选择Python3, ...

  9. 一台电脑上配置多个git账号(gitee),向不同git线上仓库提交(命令行/TortoiseGit同时) 代码

    目录 1.一台电脑上实现与多个git在线仓库提交代码的实际场景 2.安装git TortoiseGit 生成SSH key 和 git的.ssh目录 创建并配置config文件 2.1.首先必须先安装 ...

最新文章

  1. 取消管理员取得所有权_win7管理员取得所有权批处理 - 卡饭网
  2. BlazorCharts 原生图表库的建设历程
  3. 【水】对于算法的个人理解
  4. Java程序员的级别定义: 对号入座, 你在哪个阶段心里要有点数
  5. poj2689Prime Distance
  6. 审计MySQL 8.0中的分类数据查询
  7. 将adb命令打包成脚本
  8. OverflowError: int too large to convert to float
  9. R:应用时间序列分析--基于R(1)第一章 时间序列分析简介
  10. PPT设计网站 驼峰设计
  11. 00002-微信小游戏--触摸事件
  12. php 导出 设置多表头,PHP Excel 导出文件,自定义表头
  13. 经典单片机c语言教程 pdf下载,51单片机经典教程.pdf
  14. java 不登录购物车_java-没有用户登录时存储购物车(playframework疑问)
  15. Uptime Kuma一款开源监控工具
  16. 解释下ArrayList集合为啥允许值为null
  17. 一张图搞清楚EOS是什么怎么工作
  18. UWA发布 | 2017 Unity手游体检蓝皮书 — MMORPG篇
  19. 画一个带统计检验的PcOA分析结果 (再进一步,配对比较)
  20. 小程序开发API之NFC

热门文章

  1. 大学学好高数的爆炸性意义!
  2. 美国著名核物理学家,前半生为美国造核弹,后半生为中国放牛
  3. 如何让nRF52840 dongle化身为BLE sniffier (过程详细记录)
  4. 免费12个月!阿里云助力中小企业0成本上云
  5. 揭秘2019双11背后的云网络 – 双11网络架构和洛神系统
  6. Sentinel 1.7.0 发布,支持 Envoy 集群流量控制
  7. Fun 3.0 发布——资源部署、依赖下载、代码编译等功能又又又增强啦!
  8. 一致性协议浅析:从逻辑时钟到Raft
  9. AI+服务 阿里巴巴如何做智能服务转型?
  10. Mendix宣布推出低代码人工智能与机器学习功能