退出登陆获取不到 Session

245 阅读1分钟

这里要说的是,如果在退出登陆时,在sendRedirect 之后使用 SecurityUtils.getSubject().logout(); 会导致 session 清空,所以在返回退出成功页面时,获取不到 session 里的任何信息。

@RequestMapping(value = "/logout", method = RequestMethod.GET)
	@LoadLog(operationType = "logout", operationName = "账号登出")
	public void logout(HttpServletRequest req, HttpServletResponse rep) {
		try {
		    rep.sendRedirect(req.getContextPath() + "/toLogout");
                // 之前是在这里先logout()
                // SecurityUtils.getSubject().logout();
		} catch (Exception e) {
			logger.error("", e);
		}
	}
 
	@RequestMapping(value = "/toLogout", method = RequestMethod.GET)
	public String toLogout(HttpServletRequest req, HttpServletResponse rep) {
            // 后来我把logout()放在了这里
	    SecurityUtils.getSubject().logout();
	    return PageUrl.toLogout;
	}

这里之前不是很明白,是什么原因,那我们就看下logout()这个方法的源码。

 public void logout() {
        try {
            clearRunAsIdentitiesInternal();
            this.securityManager.logout(this);
        } finally {
            this.session = null;
            this.principals = null;
            this.authenticated = false;
            //Don't set securityManager to null here - the Subject can still be
            //used, it is just considered anonymous at this point.  The SecurityManager instance is
            //necessary if the subject would log in again or acquire a new session.  This is in response to
            //https://issues.apache.org/jira/browse/JSEC-22
            //this.securityManager = null;
        }
    }
@After("loadLog()"
public void after(JoinPoint joinPoint) {
try {
    // 如果是退出登陆,走下面逻辑
  if ("logout".equals(operationType)) {
	 if (null != session){
	    if (session.getAttribute("id") != null) {
		String userName = (String)SecurityUtils.getSubject().getPrincipal();
		String areaName = "";
//		Manager manager = (Manager) object[0];
//		manager = managerService.selectByUsername(manager.getUserName());
		Manager manager = managerService.selectByUsername(userName);
		loadLog.setUserName(manager.getUserName());
		loadLog.setRealName(manager.getRealName());
		loadLog.setArea(areaName);
		loadLog.setPhone(manager.getPhone());
		loadLog.setLogout(new Date());
	        loadLog.setLoginIp(ip);
		loadLogService.insertSelective(loadLog);
		}
	}
   }
 } catch (Exception e) {
    // 记录本地异常日志
    logger.error("==后置通知异常==");
    logger.error("异常信息:{}", e);
	}
}

这里就发现,无论 logout()成功与否,最终,都会把 session 和 principals 清空 ,authenticated 设置为 false,也就是为什么不能在 redirect 之后直接 SecurityUtils.getSubject().logout();

直接 logout()的话只会让你要在 AOP After () 这个切面获取用户信息的时候获取不到 session 里任何东西。

这也算是一个小的知识点吧,可能会踩到的雷,如果遇到的朋友们,可以增强点意识,如果是才遇到的朋友们,当做个警醒,以后不要踩雷。

我是进阶的球儿,大家一起2019年的爬坑历程。感觉分享很给力的话给个赞,谢谢!!!有问题也可以下方留言沟通。