前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >黑马瑞吉外卖之过滤器后台登录验证(详细笔记说明)

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

作者头像
兰舟千帆
发布2022-08-03 18:16:31
6100
发布2022-08-03 18:16:31
举报

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

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

在这里插入图片描述
在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述

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

代码逻辑如下:

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

代码语言:javascript
复制
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")

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

代码语言:javascript
复制
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
//        获取本次请求的uri
        String requestURI = request.getRequestURI();

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

代码语言:javascript
复制
   定义不需要处理的路径包含请求的静态资源
        String[] urls = new String[]{
                "/employee/login",
                "/employee/logout",
                "/backend/**",
                "/front/**",
                "/common/**",
                "/user/sendMsg",//移动端发送短信
                "/user/login",//移动端登录

        };

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

代码语言:javascript
复制
    boolean check = check(urls, requestURI);//判断是否相同,如果和放行路径相同,就不会进行处理
//        如果不需要处理就放行
        if(check)
        {
            log.info("本次请求{}不需要处理",requestURI);
            filterChain.doFilter(request,response);
            return;
        }

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

代码语言:javascript
复制
 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;
    }

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

在这里插入图片描述
在这里插入图片描述

所以我们这里也进行一个判断,获取这个值,没有获取到就是没有登录,获取到就是登录了。

代码语言:javascript
复制
  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;
        }

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

代码语言:javascript
复制
 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;
        }

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

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

代码语言:javascript
复制
   log.info("用户未登录");
//        如果未登录则返回未登录结果
        response.getWriter().write(JSON.toJSONString(R_.error("NOTLOGIN")));
        log.info("拦截到请求:{}",request.getRequestURI());
        return;

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

我们打开R,最主要的这里会在这里设置一个0。

在这里插入图片描述
在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述

完整代码。

代码语言:javascript
复制
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;
    }
}

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-07-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 黑马瑞吉外卖之过滤器后台登录验证
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档