作为一名小白,初遇到这种业务也着实头疼了一段时间。经历了各种查资料,总结出了一个相对简便的方法。
首先在登陆之后使用
Collection list = sessionDAO.getActiveSessions();
方法获取到所有登录的用户,循环该list,取到集合中单个的session对象
Subject s = new Subject.Builder().session(session).buildSubject();
获取到subject, 然后s.isAuthenticated()判断该subject是否通过验证。
User user = (User) s.getPrincipal();
获取到登录用户,然后判断当前登录用户是否存在于已登录用户中,自己的user.getid 等于 循环出的user.getid的话说明用户已经登录了。
这时可以给session加个标识,标识已经踢出了。
这里是我写的例子。
Collection list = sessionDAO.getActiveSessions();
String principal= (String)token.getPrincipal();
for (Session session: list) {
Subject s = new Subject.Builder().session(session).buildSubject();
if (s.isAuthenticated()) {
User user = (User) s.getPrincipal();
if(user!=null){
if (user.getCode().equals(principal)) {
if (!session.getId().equals(
getSession().getId())) {
//session.setAttribute("error", "账号重复登录!");
session.setAttribute("kicked", true);
}
}
}
}
}
至于为什么加标识而不是直接注销之前登录的用户呢,因为这里注销的话用户那里莫名其妙的就自己退出了,用户根本不知道发生了什么,所以最好建立个file提示一下再注销。
Filter中首先先判断kicked是否为true,不为true就直接放过吧
然后判断是否是ajax请求
booleanisAjax=req.getHeader("X-Requested-With")!=null&& "XMLHttpRequest".equals(req.getHeader("X-Requested-With").toString());
如果不是ajax请求的话
String str = "
+ "window.top.location.href='"
+ url
+ "';";
session.setAttribute("kicked", false);
PrintWriter out = response.getWriter();
out.print(str);
out.flush();
out.close();
若是ajax请求,那么就要返回json数据啦
Map map = new HashMap();
map.put("login_status","300");
map.put("message","您的账号在异地登录,如非本人操作请尽快修改密码!");
String resJSON = JSON.toJSONString(map);
out.print(resJSON);
前端js要配合一下
if(result.login_status == 300){
layer.msg(result.message);//您的账号在异地登录....
//然后跳转网页
}
这样既可实现互斥登录功能。
一个很基础很简单的方法,在此写下博客记录下来,用于提醒自己,以及帮助以后会遇到这样的问题的人。O(∩_∩)O~。。。