这里要说的是,如果在退出登陆时,在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年的爬坑历程。感觉分享很给力的话给个赞,谢谢!!!有问题也可以下方留言沟通。