后端逻辑机制实现相关:单一登陆,使用session监听+spring MVC拦截器禁止用户重复登录

web项目中禁止用户重复登录。一般来说有两种做法:

         一是在用户表中维护一个字段(是否在线),用户登录时,设定值为true,用户退出时设定为false,在重复登录时,检索到该字段为true时,禁止用户登录。这种方法有明显的漏洞,及用户在非正常情况退出(关闭浏览器、关机等)是,该字段值一直为true,会导致用户无法登录。

          而另一种比较通用的做法是使用session监听,重复登录后,强制之前登录的session过期,从而踢出了该用户。

1.web.xml中配置session监听类

<listener>
   <listener-class>com.energy.ims.util.Session.SessionListener</listener-class>
</listener>

2.session监听的SessionListener

package com.energy.ims.util.Session;


import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;


public class SessionListener implements HttpSessionListener {


public static SessionContext sessionContext=SessionContext.getInstance();

public void sessionCreated(HttpSessionEvent httpSessionEvent) {
    sessionContext.AddSession(httpSessionEvent.getSession());
    }
 
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        sessionContext.DelSession(httpSessionEvent.getSession());
    }
}

3.SessionContex类(使用单例模式)

package com.energy.ims.util.Session;


import java.util.HashMap;


import javax.servlet.http.HttpSession;


public class SessionContext {


private static SessionContext instance;
    private HashMap<String,HttpSession> sessionMap;
 
    private SessionContext() {
    sessionMap = new HashMap<String,HttpSession>();
    }
 
    public static SessionContext getInstance() {
        if (instance == null) {
            instance = new SessionContext();
        }
        return instance;
    }
 
    public synchronized void AddSession(HttpSession session) {
        if (session != null) {
        sessionMap.put(session.getId(), session);
        }
    }
 
    public synchronized void DelSession(HttpSession session) {
        if (session != null) {
        sessionMap.remove(session.getId());
            if(session.getAttribute("userid")!=null){
            sessionMap.remove(session.getAttribute("userid").toString());
            //session.invalidate(); 
            }
        }
    }
 
    public synchronized HttpSession getSession(String session_id) {
        if (session_id == null) return null;
        return (HttpSession) sessionMap.get(session_id);
    }
 
public HashMap getSessionMap() {
return sessionMap;
}
 
public void setMymap(HashMap sessionMap) {
this.sessionMap = sessionMap;
}
 
}

4.用户登陆成功,取用户id作为sessionMap中的key,判断用户是否已经登陆;若未登陆,将userid和浏览器session保存到sessionMap中,若已经登陆,强制原SessionMap过期,替换value值。以此机制保证用户唯一登陆标识。

public xxxx  xxxxxx(){    //执行登陆验证,登陆成功执行如下:    

        session.setAttribute("userid", user.getId());

        String userid=session.getAttribute("userid").toString();
        //判断,清除在线用户后,更新map,替换map中value的值(session)
        if(SessionListener.sessionContext.getSessionMap().get(userid)!=null){
        SessionListener.sessionContext.getSessionMap().remove(userid);
        SessionListener.sessionContext.getSessionMap().remove(session.getId());
        SessionListener.sessionContext.getSessionMap().put(userid,session);
        }else{
        // 根据当前sessionid 取session对象。 更新map key=用户名 value=session对象 删除map
        SessionListener.sessionContext.getSessionMap().put(userid,session);
        SessionListener.sessionContext.getSessionMap().remove(session.getId());

        }

}

.5.拦截器,(springMVC配置不进行叙述

    拦截器从session中取出用户信息,判断session未失效后,取出用户信息,获取服务器中sessionMap中的该用户对应value值(usersession),比较服务器中保存的用户登陆信息usersession同当前浏览器session是否一致,从而拦截跳转

//根据登陆用户,获取服务器中封装的sessionMap中的value值
HttpSession userSession=(HttpSession)SessionListener.sessionContext.getSessionMap().get(((SysUserinfoVO)sessionUser).getId() + "");
//服务器sessionMap中value值和浏览器session对比是否一致
if(userSession != session) {
redirect(request, response); //封装的跳转方法,可自行定义跳转到登陆页面
return false;
}
如上可实现web项目,禁止用户重复登录机制
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不许赖zhang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值