方法一:比较复杂,在项目比较小没引用消息中间件的情况下且没有redis
MyMapSessionId类(采用单例模式,对象有且只有一个,存在的时候不用创建,为空的时候创建对象) 用于用户登入时保存sessionId , 作为后期对同一帐号是否多地登入作工具(如果项目中引用了redis做缓存这个类可以省略)
public class MyMapSessionId {
private static MyMapSessionId m;
private HashMap<Long,String> mymap;
private MyMapSessionId() {
mymap = new HashMap<Long,String>();
}
public static synchronized MyMapSessionId getInstance() {
if (m == null) {
m = new MyMapSessionId();
}
return m;
}
public synchronized void AddSession(Long id, String sessionID) {
mymap.put(id, sessionID);
}
public String getSessionId(Long id) {
String SessionId = (String) mymap.get(id);
return SessionId;
}
public synchronized void DeleteSessionId(Long id){
mymap.remove(id);
}
}
/** * 用户登录拦截器 * @author :geng * @date :2017-12-19 9:37 */
public class UserAccountInfoLoginInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String requestHeader = request.getHeader("X-Requested-With"); //查询用户是否登录 UserAccountInfo userAccountInfo = (UserAccountInfo) request.getSession().getAttribute(Session_Constant.USERACCOUNTINFO); if (userAccountInfo !=null){ HttpSession session = request.getSession(); String Id = session.getId();//获取当前会话sessionId Long id = userAccountInfo.getId(); MyMapSessionId m = MyMapSessionId.getInstance(); String sessionId = m.getSessionId(id);//获取保存的sessionId if (sessionId!=null && sessionId.equals(Id)) { return true; } else { session.invalidate(); String str="yideng";//已登录 request.getRequestDispatcher("/portal/denglu?ab="+str).forward(request,response); } return true; }else { //检查是否是ajax请求 if (StringUtil.isNotEmpty(requestHeader) && requestHeader.equalsIgnoreCase("XMLHttpRequest")){ response.getWriter().print("logout"); }else { response.sendRedirect(StringUtil.getBasePath(request)+"/portal/denglu"); } return false; } } }
/** * 跳转登录页面 */ @GetMapping("/denglu") public String todenglu() throws ServletException, IOException { response.setHeader("Access-Control-Allow-Origin", "*"); response.setContentType("text/html; charset=utf-8"); //查询用户是否登录 UserAccountInfo userAccountInfo = (UserAccountInfo) session.getAttribute(Session_Constant.USERACCOUNTINFO); UserAccountSafeInfo userAccountSafeInfo = (UserAccountSafeInfo) request.getSession().getAttribute(Session_Constant.USERACCOUNTSAFEINFO); String str = request.getParameter("ab"); if (userAccountInfo != null && userAccountSafeInfo != null) { return "portal/denglu"; } else { if (str != null && !str.trim().isEmpty()) { // 判断是否是因为被挤下来而被跳转到登入页面 request.setAttribute("Msg", "您的账号已经在另一处登录,请重新登录!"); } return "portal/denglu"; /* request.getRequestDispatcher("portal/denglu").forward(request,response);*/ } }
/** * 用户的登录jsp页面 */
<script> //处理账号同时登录时挤掉另一个账号 var Msg= '${Msg}'; if (aabb != null && aabb != "") { alert(Msg);// } </script>
/** * 用户的登录controller */ @RequestMapping("/login") @ResponseBody public Map<String, Object> login(String mobile, Model model, String password) {
//简单的密码手机号校验逻辑省略
Map<String, Object> hashmap = new HashMap<>();
Long id = userinfo.getId();// 登录用户(如果后期需要加密需要对其进行加密处理) HttpSession session = request.getSession(); String sessionId = session.getId(); MyMapSessionId.getInstance().AddSession(id, sessionId);// 将用户的id和当前会话sessionId绑定 //如果登录成功 hashmap.put("loginResult", "登录成功"); return hashmap;
}
方法二:在有redis和token情况下,就会变得简单很多
/** * 拦截器 * * @Description TODO * @author geng * @date: 2018年3月27日 下午2:17:05 */
public class Interceptor extends HandlerInterceptorAdapter {
private static final Logger logger = LoggerFactory.getLogger(AppInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
/**
* 对来自后台的请求统一进行日志处理
*/
// 签名处理过程 start....
AppReturnBean returnBean = new AppReturnBean();
String token = request.getHeader("Authorization");
System.out.println("token =" + token);
if (StringUtil.isEmpty(token)) {
returnBean.setRespDesc("请求失败,token参数不存在");
returnBean.setRespCode(App_Constant.FAIL);
StringUtil.sendJsonData(response, JSON.toJSONString(returnBean));
return false;
}
try {
/* 校验token */
JWToken.verifyToken(token);
Long baseId = JWToken.getBaseId(request);
String tokeninredis = JedisUtils.get(baseId + "baseId");
if (!token.equals(tokeninredis)) {
returnBean.setRespDesc("异地登录");
returnBean.setRespCode(App_Constant.FAIL);
StringUtil.sendJsonData(response, JSON.toJSONString(returnBean));
return false;
}
} catch (Exception e) {
e.printStackTrace();
returnBean.setRespDesc("Token验证失败,请重新获取");
returnBean.setRespCode(App_Constant.TOKEN_FAIL);
StringUtil.sendJsonData(response, JSON.toJSONString(returnBean));
return false;
}
/** * 用户的登录controller */
@RequestMapping("/login") @ResponseBody public AppReturnBean login(String mobile, Model model, String password, String longitude, String latitude) { String token = request.getHeader("Authorization");//得到token令牌 AppReturnBean appReturnBean = new AppReturnBean(); Map<String, Object> hashmap = new HashMap<>();
//省略校验和逻辑
String tokeninredis = JedisUtils.get(baseId + "baseId"); //处理异浏览器手机登录 if (!token.equals(tokeninredis)) { JedisUtils.set(baseId + "baseId", token); }
}