在网上有很多解决限制登录的方法,包括springsecurity也有解决的方案,今天记录一下使用javaweb的实现
知识点
思路如下:
演示
具体实现:
1.维护一个map集合
public class loginusermap { private static map<string, string> loginusermap = new concurrenthashmap<string, string>(); /** * set方法 * * @param loginid 用户唯一标识,用户名或者用户id * @param sessionid sessionid */ public static void setloginusermap(string loginid, string sessionid) { loginusermap.put(loginid, sessionid); } /** * get方法 * * @return */ public static map<string, string> getloginusermap() { return loginusermap; } /** * 根据sessionid移除map中的值 * * @param sessionid */ public static void removeuser(string sessionid) { for (map.entry<string, string> entry : loginusermap.entryset()) { if (sessionid.equals(entry.getvalue())) { loginusermap.remove(entry.getkey()); break; } } } /** * 判断用户是否在map中 * * @param loginid * @param sessionid * @return */ public static boolean isinloginusers(string loginid, string sessionid) { return (loginusermap.containskey(loginid) && sessionid.equals(loginusermap.get(loginid))); }
2.实现一个session监听
session销毁能及时更新map
@weblistener public class sessionlistener implements httpsessionlistener { private logger logger=loggerfactory.getlogger(sessionlistener.class); @override public void sessioncreated(httpsessionevent httpsessionevent) { } @override public void sessiondestroyed(httpsessionevent httpsessionevent) { httpsession session = httpsessionevent.getsession(); string sessionid = session.getid(); //session销毁时消除loginusermap中的sessionid loginusermap.removeuser(sessionid); logger.info("session销毁,sessionid:"+sessionid); } }
3.定义过滤器
可自定义一个过滤器,但要排除登录请求(略),核心代码如下
//判断是否重复登录 string loginname = username.getloginname();//获取用户唯一标识 //判断当前用户session是否改变 if (!loginusermap.isinloginusers(loginname,session.getid())) { //定义自己的实现方式,被挤下线,我的是: //session发送改变,表示别处登录 //被挤下线,清除session,提示信息,实现跳转 request.setattribute("online",false); request.getrequestdispatcher("/logout.do").forward(request,response); return; } chain.dofilter(new xsshttpserlet((httpservletrequest) request), response);
4.注册监听和过滤器
<filter> <filter-name>loginlimitfilter</filter-name> <filter-class>io.github.brightloong.loginlimite.loginlimitfilter</filter-class> </filter> <filter-mapping> <filter-name>loginlimitfilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
另外,可以设置轮询的方式判断,让用户及时下线,但消耗资源,我采取的是请求失败跳转的方式,直接调用退出登录的接口
总结
实现无法解决同一浏览器多次登录的问题,及sessionid相同,但能实现基本的限制登录的操作,因为做的是踢线下,所以相比账号在线,无法登录来说,稍微简单,若做第二种形式,则需要考虑session是否消除的问题。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论