文章目录
- 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;}
}