zoukankan      html  css  js  c++  java
  • 简单的登录权限验证实现

    1.登录

    登录时需要生成一个自定义的token,token的生成规则一般可以考虑混合多种因素,如userId+生成时间+UUID,再进行一定的编码

    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.xml中加入

    <listener> 
    <listener-class>com.project.listener.SessionListener</listener-class> 
    </listener>
    
    <!-- session超时定义,单位为分钟 -->
    <session-config>
    <session-timeout>1440</session-timeout> <!--1440分钟(1天)后失效 -->
    </session-config>

    project自行修改为当前项目名

    在session过期时清除map

    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过滤请求,使未登录用户自动跳转到登录页

    <!-- 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登录页本身设置成不能被拦截

    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中进行重定向跳转时,外部顶层页面并不会进行跳转。

  • 相关阅读:
    LeetCode 10 Regular Expression Matching(字符串匹配)
    LeetCode 9 Palindrome Number(回文数字判断)
    操作系统期末复习资料分享
    计算机网络那些事~(二)
    seL4之hello-3征途
    计算机网络那些事~(一)
    seL4之hello-2旅途(完成更新)
    博客声明
    seL4环境配置
    Canvas链式操作
  • 原文地址:https://www.cnblogs.com/Orange42/p/6881840.html
Copyright © 2011-2022 走看看