文章目录
- 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" required
lay-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)
@ResponseBody
public ResponseData CheckLogin(HttpServletRequest request, HttpServletResponse httpServletResponse) {
// Boolean flag = false;//true-已经登陆 false-未登陆或登陆session一样
String ip = "";//返回空-未登录。非空-已登录
Map<String, Object> mmap = new HashMap<>();
try {
//获取当前用户的sessionId
String sessionId = request.getSession().getId();//当前sessionid
String 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 {
//获取老sessionId
String sessionIdOld = (String) request.getServletContext().getAttribute(username);
if (null != sessionIdOld && !sessionId.equals(sessionIdOld)) {
//注销老session
HttpSession 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;
}
}