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

  • 相关阅读:
    织梦开发——相关阅读likeart应用
    织梦标签教程
    织梦专题调用代码
    HIT 2543 Stone IV
    POJ 3680 Intervals
    HIT 2739 The Chinese Postman Problem
    POJ 1273 Drainage Ditches
    POJ 2455 Secret Milking Machine
    SPOJ 371 Boxes
    HIT 2715 Matrix3
  • 原文地址:https://www.cnblogs.com/Orange42/p/6881840.html
Copyright © 2011-2022 走看看