Shiro单点登录 并实现PC端和手机端能同时在线
本文适用于有一定shiro使用经验的人。因为最近遇到需要在项目中拓展PC端和手机端同时在线,且满足单点登录。由于之前接手代码已经实现PC端单点登录,以及数据处理,在此基础上做的拓展。废话不多说直接上代码
1.shiro实现单点登录
登录时候,在校验是否认证的时候进行处理
currentUser.isAuthenticated()
当校验到用户已经认证以后,对Session进行处理。处理思路是,shiro校验成功之后,先查询Session。如果没有 ,就存入一个Session,成功登录。如果已有session,就判断是否为同一浏览器登录,是 则不改变session 成功登录。不为同一浏览器,则删除之前那个session,再存入一个session 成功登录。
Collection<Session> sessions = sessionDAO.getActiveSessions();
if (sessions.size() >= 1) {
for (Session session : sessions) {
// java8 Optional类 主要做判空处理
Optional<Object> user_computer = Optional.ofNullable(session.getAttribute("USER_COMPUTER_SESSION"));
if (user_computer.isPresent()) {
// 判断是否是同一浏览器
if (SecurityUtils.getSubject().getSession().getId().equals(session.getId())) {
break;
}
User sysUser = (User) user_computer.get();
if(dto.getUserName().equals(sysUser.getUsername())) {
session.setTimeout(0);
sessionDAO.delete(session);
}
}
}
}
2.实现PC端可手机端同时在线
刚开始的时候,还在那纠结怎么区分处理session,防止误删之前已经登录成功的session。
后面突然顿悟!
登录控制器的时候,用HttpServletRequest request 获取登录进来的User-Agent对登录的设备进行一个判断 给session取名的时候再有一个区分
String header = request.getHeader("User-Agent");
if (header.contains("Windows")||header.contains("Intel Mac OS X")||header.contains("PostmanRuntime")){}
else if(header.contains("Android")||header.contains("iPad")||header.contains("iPhone")){}
实现策略很多种,个人觉得这种方法简单粗暴好用