1.登陸html
登陸時須要生成一個自定義的token,token的生成規則通常能夠考慮混合多種因素,如userId+生成時間+UUID,再進行必定的編碼java
String token=userId+UUID.randomUUID().toString(); 而後將生成的token放入session request.getSession().setAttribute("token", token); 並將該token管理起來 public static Map<String, String> userLoginInfoMap = new ConcurrentHashMap<String, String>(); loginMap.put(session.getId(), token);
2.設置session的過時時間web
在web.xml中加入apache
<listener> <listener-class>com.project.listener.SessionListener</listener-class> </listener> <!-- session超時定義,單位爲分鐘 --> <session-config> <session-timeout>1440</session-timeout> <!--1440分鐘(1天)後失效 --> </session-config>
project自行修改成當前項目名session
在session過時時清除mapapp
package com.project.listener; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; public class SessionListener implements HttpSessionListener { //Session建立時的方法 public void sessionCreated(HttpSessionEvent event) { } public void sessionDestroyed(HttpSessionEvent event) { HttpSession session = event.getSession(); synchronized (this) { loginMap.remove(session.getId()); } } }
3.使用Filter過濾請求,使未登陸用戶自動跳轉到登陸頁dom
<!-- Filter過濾未受權用戶 --> <filter> <filter-name>LoginFilter</filter-name> <filter-class>com.project.filter.LoginFilter</filter-class> <!-- 定義Filter過濾的忽略列表 --> <init-param> <param-name>ignores</param-name> <param-value>/login.jsp</param-value> </init-param> </filter> <filter-mapping> <filter-name>LoginFilter</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping>
攔截全部的jsp頁面請求,這裏login.jsp登陸頁自己設置成不能被攔截jsp
package com.project.filter; import java.io.IOException; import java.io.PrintWriter; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.lang3.StringUtils; public class LoginFilter extends HttpServlet implements Filter { private static final long serialVersionUID = 1L; private Set<String> prefixIignores = new HashSet<String>(); public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) arg0; HttpServletResponse response = (HttpServletResponse) arg1; String url = request.getRequestURI(); // 過濾忽略列表 for (String ignore : prefixIignores) { if (url.startsWith(ignore)) { arg2.doFilter(request, response); return; } } HttpSession session = request.getSession(); String token = (String)session.getAttribute("token"); if (StringUtils.isNotBlank(token) && loginMap.get(session.getId()) == token) { arg2.doFilter(request, response); } else { // 判斷獲取的路徑不爲空且不是訪問登陸頁面或執行登陸操做時跳轉 if (url != null && !url.equals("") && (url.indexOf("Login") < 0 && url.indexOf("login") < 0)) { //重定向到登陸頁 //response.sendRedirect(request.getContextPath() + "/login.jsp"); //使用重定向沒法解決在iframe中跳轉的問題,因此使用window.top.location跳轉 response.setContentType("text/html;charset=UTF-8"); response.setCharacterEncoding("UTF-8");// 防止彈出的信息出現亂碼 String loginUrl="http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath()+"/login.jsp"; //登陸頁URL PrintWriter out = response.getWriter(); out.print("<script>alert('登陸信息已失效!')</script>"); out.print( "<script>window.top.location="+"\""+loginUrl+"\""+"</script>"); out.flush(); out.close(); } } return; } public void init(FilterConfig config) throws ServletException { if (config == null) { return; } // 初始化忽略列表 String cp = config.getServletContext().getContextPath(); String ignoresParam = config.getInitParameter("ignores"); String[] ignoreArray = ignoresParam.split(","); for (String s : ignoreArray) { prefixIignores.add(cp + s); } } }
在filter的init-param中設置的頁面將不被攔截,加入到prefixIignores忽略列表,在doFilter攔截到的頁面先判斷是不是忽略列表,若是是的話就不攔截,不是的話再進行後續攔截,當檢測到token無效時引導用戶跳轉到登陸頁從新登陸,這裏不使用重定向的方式,由於當在iframe中進行重定向跳轉時,外部頂層頁面並不會進行跳轉。this