• 黑马瑞吉外卖之过滤器后台登录验证(详细笔记说明)


    黑马瑞吉外卖之过滤器后台登录验证

    上次文章我们完成了后台的登录和退出的功能,现在我们做一个登录验证。思路是这样的,我们正常的思路是访问登录界面然后输入信息验证,然后我们到达管理界面。但是如果直接访问管理界面的链接,也可以进去,这样的话,登录的作用还有什么意义呢?
    在这里插入图片描述

    所以我们加入过滤器。这个过滤器啊主要是对请求路径的一个处理。之前我们还做过静态资源映射。这个静态资源映射主要是为了防止加载必要资源加载不到,这个静态资源的访问需要做一个映射。
    在这里插入图片描述

    过滤器这里对访问的请求路径做出了处理。后面我们会有多个访问请求路径。

    代码逻辑如下:

    我们首先对所有的路径进行一个拦截

    @WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
    
    • 1

    需要获取到请求路径,把响应response,以便后面做出响应处理

            HttpServletRequest request = (HttpServletRequest) servletRequest;
            HttpServletResponse response = (HttpServletResponse) servletResponse;
    //        获取本次请求的uri
            String requestURI = request.getRequestURI();
    
    • 1
    • 2
    • 3
    • 4

    过滤器这里都写好了。如果用户请求的这个路径直接就是登录和退出我们就没必要进行拦截处理,这个过滤器主要是未登录用户的非法访问的处理。点击退出的本来就已经登录吗,不需要验证,要登录的没有进行非法访问,其他的是各种资源路径我们没有必要去验证。移动端是移动端的和后台管理无关。

       定义不需要处理的路径包含请求的静态资源
            String[] urls = new String[]{
                    "/employee/login",
                    "/employee/logout",
                    "/backend/**",
                    "/front/**",
                    "/common/**",
                    "/user/sendMsg",//移动端发送短信
                    "/user/login",//移动端登录
    
            };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    对请求路径与定义的放行的路径对比

        boolean check = check(urls, requestURI);//判断是否相同,如果和放行路径相同,就不会进行处理
    //        如果不需要处理就放行
            if(check)
            {
                log.info("本次请求{}不需要处理",requestURI);
                filterChain.doFilter(request,response);
                return;
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这个check方法我们定义在后面

     public  boolean check(String[] urls,String requestURI)
        {
            for(String url:urls)
            {
                boolean match = PATH_MATCHER.match(url, requestURI);
                if(match==true)
                {
                    return  true;
                }
    
            }
            return false;
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    还有一个判断就是如果你能获取到用户id就可以判断已经登录了,因为我们之前在用户登录的时候会存储他的id在session。没有登录就没有存储这个id,登录的话就会存储到

    在这里插入图片描述
    所以我们这里也进行一个判断,获取这个值,没有获取到就是没有登录,获取到就是登录了。

      Object employee = request.getSession().getAttribute("employee");
            if (employee!=null)
            {
                long id = Thread.currentThread().getId();
                log.info("当前线程的id为{}",id);
                log.info("用户已经登录,用户id为{}",employee);
                BaseContext.setCurrentId((Long)employee);
                filterChain.doFilter(request,response);
                return;
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    其实还有一个移动端的登录验证,一样的道理,后面我们移动端页面会用到

     Object user = request.getSession().getAttribute("user");
            if (user!=null)
            {
                long userid = Thread.currentThread().getId();
                log.info("当前线程的id为{}",userid);
                log.info("用户已经登录,用户id为{}",userid);
                BaseContext.setCurrentId((Long)userid);
                filterChain.doFilter(request,response);
                return;
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    这些只要有一步验证成功,过滤器就返回,不要继续往下走了。因为下面我们要进行拦截处理了。

    来看怎么处理。这里我们还进行了跟踪打印日志

       log.info("用户未登录");
    //        如果未登录则返回未登录结果
            response.getWriter().write(JSON.toJSONString(R_.error("NOTLOGIN")));
            log.info("拦截到请求:{}",request.getRequestURI());
            return;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    你看我们这里的响应了一个R_.error,返回了JSON.这个R_.error的作用是什么?

    我们打开R,最主要的这里会在这里设置一个0。
    在这里插入图片描述
    但是这时你会有疑问,这个写入的到底在哪里响应呢,如果回退到登录
    界面。其实是在一个js文件当中,来看,前端这里的一个响应拦截器。这下你就完全清除了。所以这个具体的逻辑过程,还是需要十分清楚的。
    在这里插入图片描述

    完整代码。

    package com.jgdabc.entity.filter;
    
    import com.alibaba.fastjson.JSON;
    import com.jgdabc.common.BaseContext;
    import com.jgdabc.common.R_;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.util.AntPathMatcher;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    //判断用户是否登录,没有登录就退回到登录界面
    @WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
    @Slf4j
    public class LoginCheckFilter implements Filter {
    //    路径匹配器,支持通配符
        public  static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            HttpServletRequest request = (HttpServletRequest) servletRequest;
            HttpServletResponse response = (HttpServletResponse) servletResponse;
    //        获取本次请求的uri
            String requestURI = request.getRequestURI();
            log.info("拦截到请求:{}",requestURI);
    //        判断用户是否登录
    //        定义不需要处理的路径包含请求的静态资源
            String[] urls = new String[]{
                    "/employee/login",
                    "/employee/logout",
                    "/backend/**",
                    "/front/**",
                    "/common/**",
                    "/user/sendMsg",//移动端发送短信
                    "/user/login",//移动端登录
    
            };
            boolean check = check(urls, requestURI);//判断是否相同,如果和放行路径相同,就不会进行处理
    //        如果不需要处理就放行
            if(check)
            {
                log.info("本次请求{}不需要处理",requestURI);
                filterChain.doFilter(request,response);
                return;
            }
    //        判断登录状态,如果已经登录,则直接放行
            Object employee = request.getSession().getAttribute("employee");
            if (employee!=null)
            {
                long id = Thread.currentThread().getId();
                log.info("当前线程的id为{}",id);
                log.info("用户已经登录,用户id为{}",employee);
                BaseContext.setCurrentId((Long)employee);
                filterChain.doFilter(request,response);
                return;
            }
    //        移动端登录验证
            Object user = request.getSession().getAttribute("user");
            if (user!=null)
            {
                long userid = Thread.currentThread().getId();
                log.info("当前线程的id为{}",userid);
                log.info("用户已经登录,用户id为{}",userid);
                BaseContext.setCurrentId((Long)userid);
                filterChain.doFilter(request,response);
                return;
            }
    
    
    
            log.info("用户未登录");
    //        如果未登录则返回未登录结果
            response.getWriter().write(JSON.toJSONString(R_.error("NOTLOGIN")));
            log.info("拦截到请求:{}",request.getRequestURI());
            return;
    
        }
    
    
    
    //    检查本次请求是否需要放行
        public  boolean check(String[] urls,String requestURI)
        {
            for(String url:urls)
            {
                boolean match = PATH_MATCHER.match(url, requestURI);
                if(match==true)
                {
                    return  true;
                }
    
            }
            return false;
        }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98

    基本是详细说明了整个过程分析。千万不要迷迷糊糊的写代码学习。

  • 相关阅读:
    山西828 B2B企业节进行时 华为携手合作伙伴共探数字化转型
    【python】二:基础学习-组织架构函数等
    SpringMVC 学习(十)之异常处理
    Python哪个版本最稳定好用2023.10.19
    web上构建3d效果 基于three.js的实例
    springcloud3 指定nacos的服务名称和配置文件的group,名称空间
    工欲善其事,必先利其器,五款实用的办公软件推荐
    Linux Docker图形化工具Portainer如何进行远程访问?
    华为云云耀云服务器L实例评测|认识redis未授权访问漏洞 & 漏洞的部分复现 & 设置连接密码 & redis其他命令学习
    DAY17-深度学习100例-卷积神经网络(CNN)识别眼睛状态
  • 原文地址:https://blog.csdn.net/jgdabc/article/details/125886927