- 浏览: 3361259 次
- 性别:
- 来自: 珠海
文章分类
- 全部博客 (1633)
- Java (250)
- Android&HTML5 (111)
- Struts (10)
- Spring (236)
- Hibernate&MyBatis (115)
- SSH (49)
- jQuery插件收集 (55)
- Javascript (145)
- PHP (77)
- REST&WebService (18)
- BIRT (27)
- .NET (7)
- Database (105)
- 设计模式 (16)
- 自动化和测试 (19)
- Maven&Ant (43)
- 工作流 (36)
- 开源应用 (156)
- 其他 (16)
- 前台&美工 (119)
- 工作积累 (0)
- OS&Docker (83)
- Python&爬虫 (28)
- 工具软件 (157)
- 问题收集 (61)
- OFbiz (6)
- noSQL (12)
最新评论
-
HEZR曾嶸:
你好博主,这个不是很理解,能解释一下嘛//左边+1,上边+1, ...
java 两字符串相似度计算算法 -
天使建站:
写得不错,可以看这里,和这里的这篇文章一起看,有 ...
jquery 遍历对象、数组、集合 -
xue88ming:
很有用,谢谢
@PathVariable映射出现错误: Name for argument type -
jnjeC:
厉害,困扰了我很久
MyBatis排序时使用order by 动态参数时需要注意,用$而不是# -
TopLongMan:
非常好,很实用啊。。
PostgreSQL递归查询实现树状结构查询
http://blog.csdn.net/jrn1012/article/details/25781319
在许多web项目中,需要禁止用户重复登录。一般来说有两种做法:
一是在用户表中维护一个字段isOnLine(是否在线),用户登录时,设定值为true,用户退出时设定为false,在重复登录时,检索到该字段为true时,禁止用户登录。这种方法有明显的漏洞,及用户在非正常情况退出(关闭浏览器、关机等)是,该字段值一直为true,会导致用户无法登录。
而另一种比较通用的做法是使用session监听,重复登录后,强制之前登录的session过期,从而踢出了该用户。具体做法是:使用监听器维护服务器上缓存的sessionMap,该map是以<session.getId(),session>的键值对,在登录后,使用userid替换session.getId(),从而使得sessionMap中维护的是<userid, session>的键值对。后续该帐号重复登录时,检索到已有该帐号session则强制它过期。
1、web.xml中配置session监听
2、session监听SessionListener类
SessionContex类(使用单例模式)
3、用户登录成功后,更新session Map,如重复登录,强制之前session过期
4、spring MVC拦截器校验session是否过期,如果过期,给出提示,并跳转到登录界面。
拦截器配置
拦截器authInterceptor
以上方式完成了禁止用户重复登录的功能,并将踢出之前登录的帐号,这在不同的浏览器中使用没有问题。但是因为在同一个浏览器中,多个标签页(Tab页)是共享session的,在同一个浏览器中并不会创建一个新的session。所以同一个浏览器还是可以重复登录的,目前还没有什么很好解决办法。本来想如果重复登录,则通过校验session是否存在来禁止登录。但是之前登录的若关闭了标签页,则在这个浏览器上的其他标签页则再也无法登录了。所以这个做法也有问题。
在许多web项目中,需要禁止用户重复登录。一般来说有两种做法:
一是在用户表中维护一个字段isOnLine(是否在线),用户登录时,设定值为true,用户退出时设定为false,在重复登录时,检索到该字段为true时,禁止用户登录。这种方法有明显的漏洞,及用户在非正常情况退出(关闭浏览器、关机等)是,该字段值一直为true,会导致用户无法登录。
而另一种比较通用的做法是使用session监听,重复登录后,强制之前登录的session过期,从而踢出了该用户。具体做法是:使用监听器维护服务器上缓存的sessionMap,该map是以<session.getId(),session>的键值对,在登录后,使用userid替换session.getId(),从而使得sessionMap中维护的是<userid, session>的键值对。后续该帐号重复登录时,检索到已有该帐号session则强制它过期。
1、web.xml中配置session监听
<listener> <listener-class>com.cnpc.framework.listener.SessionListener</listener-class> </listener>
2、session监听SessionListener类
package com.cnpc.framework.listener; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; import com.cnpc.framework.utils.SessionContext; 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()); } }
SessionContex类(使用单例模式)
package com.cnpc.framework.utils; 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; } }
3、用户登录成功后,更新session Map,如重复登录,强制之前session过期
public void sessionHandlerByCacheMap(HttpSession session){ String userid=session.getAttribute("userid").toString(); if(SessionListener.sessionContext.getSessionMap().get(userid)!=null){ HttpSession userSession=(HttpSession)SessionListener.sessionContext.getSessionMap().get(userid); //注销在线用户 userSession.invalidate(); SessionListener.sessionContext.getSessionMap().remove(userid); //清除在线用户后,更新map,替换map sessionid SessionListener.sessionContext.getSessionMap().remove(session.getId()); SessionListener.sessionContext.getSessionMap().put(userid,session); } else { // 根据当前sessionid 取session对象。 更新map key=用户名 value=session对象 删除map SessionListener.sessionContext.getSessionMap().get(session.getId()); SessionListener.sessionContext.getSessionMap().put(userid,SessionListener.sessionContext.getSessionMap().get(session.getId())); SessionListener.sessionContext.getSessionMap().remove(session.getId()); } }
4、spring MVC拦截器校验session是否过期,如果过期,给出提示,并跳转到登录界面。
拦截器配置
<init-param> <description>Spring MVC配置文件</description> <param-name>contextConfigLocation</param-name> <param-value>classpath:controller.xml</param-value> </init-param> controller.xml配置 [html] view plaincopy在CODE上查看代码片派生到我的代码片 <mvc:interceptors> <bean class="com.cnpc.framework.interceptor.AuthInterceptor" /> </mvc:interceptors>
拦截器authInterceptor
package com.cnpc.framework.interceptor; import java.io.PrintWriter; import java.util.Map; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import com.cnpc.framework.common.SessionContainer; @Component("SpringMVCInterceptor") public class AuthInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); //过滤登录、退出访问 String[] noFilters = new String[] { "/auth/login", "/auth/logout" }; String uri = request.getRequestURI(); boolean beFilter = true; for (String s : noFilters) { if (uri.indexOf(s) != -1) { beFilter = false; break; } } SessionContainer sessionContainer = (SessionContainer) request.getSession().getAttribute("SessionContainer"); if (beFilter) { if (null == sessionContainer) { //ajax方式交互 if (request.getHeader("x-requested-with") != null && request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest"))// 如果是ajax请求响应头会有,x-requested-with; { response.setHeader("sessionstatus", "timeout");// 在响应头设置session状态 return false; } // 未登录 PrintWriter out = response.getWriter(); StringBuilder builder = new StringBuilder(); builder.append("<script type=\"text/javascript\" charset=\"UTF-8\">"); builder.append("alert(\"页面过期,请重新登录\");"); builder.append("window.top.location.href='/auth/logout';"); builder.append("</script>"); out.print(builder.toString()); out.close(); return false; } else { // 添加系统日志 // ----------------------------------- // ----------------------------------- } } Map paramsMap = request.getParameterMap(); return super.preHandle(request, response, handler); } } 以上Sprring MVC拦截器在同服务器以ajax方式交互时,前台需做如下相应处理: [html] view plaincopy在CODE上查看代码片派生到我的代码片 //控制ajax请求,session超时处理页面跳转 $.ajaxSetup({ contentType:"application/x-www-form-urlencoded;charset=utf-8", complete:function(XMLHttpRequest,textStatus){ var sessionstatus=XMLHttpRequest.getResponseHeader("sessionstatus"); // 通过XMLHttpRequest取得响应头,sessionstatus, if(sessionstatus=="timeout"){ // 如果超时就处理 ,指定要跳转的页面 alert("页面过期,请重新登录"); window.top.location.href="/auth/logout"; } } } );
以上方式完成了禁止用户重复登录的功能,并将踢出之前登录的帐号,这在不同的浏览器中使用没有问题。但是因为在同一个浏览器中,多个标签页(Tab页)是共享session的,在同一个浏览器中并不会创建一个新的session。所以同一个浏览器还是可以重复登录的,目前还没有什么很好解决办法。本来想如果重复登录,则通过校验session是否存在来禁止登录。但是之前登录的若关闭了标签页,则在这个浏览器上的其他标签页则再也无法登录了。所以这个做法也有问题。
发表评论
-
Spring Boot 属性配置
2016-06-24 11:04 1145Spring Boot 属性配置和使用 http://blog ... -
Spring Boot 集成MyBatis
2016-06-24 10:55 1985Spring Boot 集成MyBatis http://bl ... -
Spring MVC防重复提交
2016-06-17 15:47 1586http://my.oschina.net/zyqjustin ... -
Spring容器加载完之后执行特定任务
2016-06-17 15:36 2237http://my.oschina.net/simpleton ... -
使用spring-session和shiro来代理session的配置
2016-06-16 11:21 11980使用spring-session和redis来代理sessio ... -
JSTL 的 if else : 有 c:if 没有 else 的处理
2016-06-14 09:52 1287http://blog.csdn.net/xiyuan1999 ... -
spring mvc 请求转发和重定向
2016-06-14 09:48 1348http://blog.csdn.net/jackpk/art ... -
mvc:view-controller
2016-05-18 10:26 1045http://blog.csdn.net/lzwglory/a ... -
spring配置事物的方式:注解和aop配置
2016-05-14 00:26 4056参考: Spring AOP中pointcut express ... -
分布式任务调度组件 Uncode-Schedule
2016-05-13 14:47 2236http://www.oschina.net/p/uncode ... -
Mybatis分库分表扩展插件
2016-05-12 15:47 1583http://fangjialong.iteye.com/bl ... -
spring+mybatis+atomikos 实现JTA事务
2016-05-11 22:00 5469sping配置多个数据源 不同用户操作不同数据库 http:/ ... -
Spring中使用注解 @Scheduled执行定时任务
2016-05-10 09:39 1529原文:http://dwf07223.blog.51cto.c ... -
Spring中配置Websocket
2016-05-05 16:55 1239spring+websocket整合(springMVC+sp ... -
redis 集群中Session解决方案之Spring Session
2016-05-04 08:54 1268集群中Session解决方案之Spring Session h ... -
使用Spring-data进行Redis操作
2016-05-04 08:54 4730使用Spring-data进行Redis操作 http://z ... -
Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC
2016-05-03 13:35 1025Spring4新特性——集成Bean Validation 1 ... -
SpringMVC介绍之Validation
2016-05-03 13:10 950SpringMVC介绍之Validation http://h ... -
spring 注解方式下使用commons-validator 验证表单
2016-05-03 11:08 3032原文: http://www.programgo.com/ar ... -
Spring MVC学习详解
2016-04-28 09:13 960原文 http://blog.csdn.net/alsocod ...
相关推荐
主要介绍了详解Spring MVC拦截器实现session控制,使用session监听,重复登录后,强制之前登录的session过期。有兴趣的可以了解一下。
主要介绍了SpringMVC拦截器实现监听session是否过期详解,还是比较不错的,这里分享给大家,供需要的朋友参考。
4、拦截器可以利用依赖注入,因此在spring框架程序中,优先拦截器 5、拦截器是包裹在过滤器中使用的。 复习 converter 转换器 i18n struts2 spring MVC 拦截器 interceptor 过滤器 filter web.xml ...
13.4.3. 拦截器(HandlerInterceptor) 13.5. 视图与视图解析 13.5.1. 视图解析器 13.5.2. 视图解析链 13.5.3. 重定向(Rediret)到另一个视图 13.5.3.1. RedirectView 13.5.3.2. redirect:前缀 13.5.3.3. forward:...
拦截器配置 @ControllerAdivce @ExceptionHandler @InitBinder @ModelAttribute 其他配置 ViewController 路径匹配参数配置 WebMvcConfigurerAdapter WebMvcConfigurer ...
13.4.3. 拦截器(HandlerInterceptor) 13.5. 视图与视图解析 13.5.1. 视图解析器(ViewResolver) 13.5.2. 视图解析链 13.5.3. 重定向(Rediret)到另一个视图 13.6. 本地化解析器 13.6.1. ...
13.4.3. 拦截器(HandlerInterceptor) 13.5. 视图与视图解析 13.5.1. 视图解析器(ViewResolver) 13.5.2. 视图解析链 13.5.3. 重定向(Rediret)到另一个视图 13.6. 本地化解析器 13.6.1. ...
13.4.3. 拦截器(HandlerInterceptor) 13.5. 视图与视图解析 13.5.1. 视图解析器 13.5.2. 视图解析链 13.5.3. 重定向(Rediret)到另一个视图 13.6. 本地化解析器 13.6.1. AcceptHeaderLocaleResolver 13.6.2....
13.4.3. 拦截器(HandlerInterceptor) 13.5. 视图与视图解析 13.5.1. 视图解析器 13.5.2. 视图解析链 13.5.3. 重定向(Rediret)到另一个视图 13.6. 本地化解析器 13.6.1. AcceptHeaderLocaleResolver 13.6.2....
8.8 拦截器 332 8.9 依赖注入 335 8.9.1 EJB注入 336 8.9.2 资源注入 339 8.10 配置EJB引用 340 8.11 使用计时器进行任务调度 342 8.12 本章小结 345 第9章 消息驱动EJB 346 9.1 JMS和EJB 347 9.1.1 为什么使用MDB ...
1. struts2的拦截器定义以及使用 153 2. struts标签 160 3. Struts 2 标签库说明及使用 160 4. set 描述 169 5. text 描述 170 6. property 描述 170 7. Struts的异常处理 171 8. Struts的上传与下载 178 五、 ...
{12.2}登录数据库}{151}{section.12.2} {12.3}创建表格}{152}{section.12.3} {12.4}关于null值}{154}{section.12.4} {12.5}操作符与实例}{154}{section.12.5} {12.5.1}where}{154}{subsection.12.5.1} {12.6}...