目录
思路:程序单用户登录,在网上查询了半天,大致是把sessionId和账号放在map中,每一个用户登录查询map中的账号所对应的sessionId是否对应,对应继续登录,不对应退出,
例如:admin账号在一处登录,登录成功的同时往全局map中put一条数据,"admin","sessionid1",在另一处登录成功时往全局map中put一条数据,"admin","sessionid2",此时键为admin的sessionid已经覆盖,在第一处操作时,会提示异地登录,因为登录时的所对应的sessionid以被覆盖,所有退出登录。
大致的思路是这样的,废话有点多,直接上代码参考(具体的业务逻辑和框架不同,会有一定偏差!)
一:编写工具类 LoginUserMap
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @ClassName LoginUserMap
* @Author haha
* @Date 2019/12/31 13:55
**/
public class LoginUserMap {
private static Map<String, String> loginUsers = new ConcurrentHashMap<String, String>();
/**
* 将用户账号和sessionId存入map
* // * @param key
* // * @param value
*/
public static void setLoginUsers(String loginId, String sessionId) {
loginUsers.put(loginId, sessionId);
}
/**
* 根据sessionId移除map中的值
*
* @param sessionId
*/
public static void removeUser(String sessionId) {
for (Map.Entry<String, String> entry : loginUsers.entrySet()) {
if (sessionId.equals(entry.getValue())) {
loginUsers.remove(entry.getKey());
break;
}
}
}
/**
* 判断账号的sessionId是否对应
*
* @param loginId
* @param sessionId
* @return
*/
public static boolean containsKey(String loginId, String sessionId) {
return sessionId.equals(loginUsers.get(loginId));
}
}
二:添加到map
在判断登录的账号密码等信息的成功的同时(判断登录方法)将账号及sessionid存入map
//账号及sessionid
LoginUserMap.setLoginUsers(loginId, session.getId());//保存sessionId到map中
三:在过滤器Filter中添加验证
loginId:当前登录人的账号(在登录成功时可以单独放在session中,重新取键名),判断是否相等,不相等时被迫下线!!
if(!LoginUserMap.containsKey(loginId, session.getId())){
//此处可直接重定向到登录页面,可返回状态值,例:type=1
PrintWriter out = response.getWriter();
StringBuilder builder = new StringBuilder();
builder.append("<script type=\"text/javascript\" charset=\"UTF-8\">");
builder.append("window.top.location.href=\"../Login.jsp?type=1\"");
builder.append("</script>");
out.print(builder.toString());
out.close();
System.out.println("该账号已在其它地方登录,您已被迫下线,如非本人操作请重新登录并及时修改密码");
}
四:前端页面判断状态值:
if (type == 1) {
layer.msg("该账号已在其它地方登录,您已被迫下线,如非本人操作请重新登录并及时修改密码");
}
ps:新的用户登录时会覆盖之前键所对应的值
有什么不清楚的可以评论哦。
才疏学浅 ,请多指教 !