登入逻辑校验流程及JWT,拦截器,过滤器的相关知识

一 登入逻辑校验流程

1,参数校验

判断前端请求携带的用户名和密码是否为空

如果是为空程序就不用往下执行了

 if (StrUtil.isBlank(loginDTO.getUsername())||StrUtil.isBlank(loginDTO.getPassword())){
            throw new CustomException("用户名和密码不能为空");
        }

2,逻辑处理

2.1 根据用户名查找到员工账户
 Emp emp=loginMapper.findUsername(loginDTO.getUsername());
2.2对账户进行数据校验如果账户为空则表示没用这个账户
if (ObjUtil.isNull(emp)){
            throw new CustomException("用户不存在");
        }
2.3对账户进行密码校验如果不一致则用户输入的密码错误
if (!StrUtil.equals(emp.getPassword(),loginDTO.getPassword())){
            throw new CustomException("用户名或密码错误");
        }

3,通过校验的数据封装

3.1生成Jwt令牌
HashMap<String, Object> claims = new HashMap<>();
        claims.put("id",emp.getId());
        String token = JwtUtils.generateJwt(claims);
3.2并且将前端需要的数据连同token一起响应给前端
return LoginVO.builder().id(emp.getId())
                .name(emp.getName())
                .username(emp.getUsername())
                .password(emp.getPassword())
                .token(token)
                .build();

二 Jwt,过滤器,拦截器的相关知识。

2.1JWT令牌

​ JWT令牌就是用户省份的标识,本质是一个字符串。

2.2 JWT全称 JSON Web Token 特点:

  • 自包含:指的是jwt令牌,看似是一个随机的字符串,但是我们是可以根据自身的需求在jwt令牌中存储自定义的数据内容。如:可以直接在jwt令牌中存储用户的相关信息。

  • 简洁:是指jwt就是一个简单的字符串。可以在请求参数或者是请求头当中直接传递。

    jwt就是将原始的json数据格式进行了安全的封装,这样就可以直接基于jwt在通信双方安全的进行信息传输了。

2.3 JWT的组成: (JWT令牌由三个部分组成,三个部分之间使用英文的点来分割)

  • 第一部分:Header(头), 记录令牌类型、签名算法等。 例如:
  • 第二部分:Payload(有效载荷),携带一些自定义信息、默认信息等。 例如:
  • 第三部分:Signature(签名),防止Token被篡改、确保安全性。将header、payload,并加入指定秘钥,通过指定签名算法计算而来。

2.4 JWT是如何将原始的JSON格式数据,转变为字符串的

  • 其实在生成JWT令牌时,会对JSON格式的数据进行一次编码:进行base64编码
  • Base64:是一种基于64个可打印的字符来表示二进制数据的编码方式。既然能编码,那也就意味着也能解码。所使用的64个字符分别是A到Z、a到z、 0- 9,一个加号,一个斜杠,加起来就是64个字符。任何数据经过base64编码之后,最终就会通过这64个字符来表示。当然还有一个符号,那就是等号。等号它是一个补位的符号
  • 需要注意的是Base64是编码方式,而不是加密方式。

2.5 生成和校验

2.5.1首先我们先来实现JWT令牌的生成。要想使用JWT令牌,需要先引入JWT的依赖:
<!-- JWT依赖-->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
2.5.2生成JWT代码实现:
Map<String, Object> claims = new HashMap<>();
    claims.put("id", 10);
    claims.put("username", "itheima");

    String jwt = Jwts.builder().signWith(SignatureAlgorithm.HS256, "aXRjYXN0")
        .addClaims(claims)
        .setExpiration(new Date(System.currentTimeMillis() + 12 * 3600 * 1000))
        .compact();

    System.out.println(jwt);
eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjcyNzI5NzMwfQ.fHi0Ub8npbyt71UqLXDdLyipptLgxBUg_mSuGJtXtBk//加密后的jwt
2.5.2 实现了JWT令牌的生成,下面我们接着使用Java代码来校验JWT令牌(解析生成的令牌):
Claims claims = Jwts.parser().setSigningKey("aXRjYXN0")
        .parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MTAsInVzZXJuYW1lIjoiaXRoZWltYSIsImV4cCI6MTcwMTkwOTAxNX0.N-MD6DmoeIIY5lB5z73UFLN9u7veppx1K5_N_jS9Yko")
        .getBody();
    System.out.println(claims);

解密后

{id=10, username=itheima, exp=1701909015}

三 过滤器Filter

3.1过滤器的特点

  • Filter表示过滤器,是 JavaWeb三大组件(Servlet、Filter、Listener)之一。
  • 过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能
    • 使用了过滤器之后,要想访问web服务器上的资源,必须先经过滤器,过滤器处理完毕之后,才可以访问对应的资源。
  • 过滤器一般完成一些通用的操作,比如:登录校验、统一编码处理、敏感字符处理等。

3.2filter的使用入门

  • 第1步,定义过滤器 :1.定义一个类,实现 Filter 接口,并重写其所有方法。

    public class DemoFilter implements Filter {
        //初始化方法, web服务器启动, 创建Filter实例时调用, 只调用一次
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("init ...");
        }
    
        //拦截到请求时,调用该方法,可以调用多次
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
            System.out.println("拦截到了请求...");
        }
    
        //销毁方法, web服务器关闭时调用, 只调用一次
        public void destroy() {
            System.out.println("destroy ... ");
        }
    }
    
  • 第2步,配置过滤器:Filter类上加 @WebFilter 注解,配置拦截资源的路径。引导类上加 @ServletComponentScan 开启Servlet组件支持。

    @WebFilter(urlPatterns = "/*") //配置过滤器要拦截的请求路径( /* 表示拦截浏览器的所有请求 )
    public class DemoFilter implements Filter {
        //初始化方法, web服务器启动, 创建Filter实例时调用, 只调用一次
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("init ...");
        }
    
        //拦截到请求时,调用该方法,可以调用多次
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
            System.out.println("拦截到了请求...");
        }
    
        //销毁方法, web服务器关闭时调用, 只调用一次
        public void destroy() {
            System.out.println("destroy ... ");
        }
    }
    

    当我们在Filter类上面加了@WebFilter注解之后,接下来我们还需要在启动类上面加上一个注解@ServletComponentScan,通过这个@ServletComponentScan注解来开启SpringBoot项目对于Servlet组件的支持。

    @SpringBootApplication
    public class TliasManagementApplication {
        public static void main(String[] args) {
            SpringApplication.run(TliasManagementApplication.class, args);
        }
    }
    

四 拦截器Interceptor

4.1定义

  • 是一种动态拦截方法调用的机制,类似于过滤器。
  • 拦截器是Spring框架中提供的,用来动态拦截控制器方法的执行。
  • 拦截器的作用:拦截请求,在指定方法调用前后,根据业务需要执行预先设定的代码。

4.2基本使用

4.2.1定义拦截器

实现HandlerInterceptor接口,并重写其所有方法

//自定义拦截器
@Component
public class DemoInterceptor implements HandlerInterceptor {
    //目标资源方法执行前执行。 返回true:放行    返回false:不放行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle .... ");
        
        return true; //true表示放行
    }

    //目标资源方法执行后执行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle ... ");
    }

    //视图渲染完毕后执行,最后执行
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion .... ");
    }
}
4.2.2 注册配置拦截器

com.itheima下创建一个包,然后创建一个配置类 WebConfig, 实现 WebMvcConfigurer 接口,并重写 addInterceptors 方法

@Configuration  
public class WebConfig implements WebMvcConfigurer {

    //自定义的拦截器对象
    @Autowired
    private DemoInterceptor demoInterceptor;

    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
       //注册自定义拦截器对象
        registry.addInterceptor(demoInterceptor).addPathPatterns("/**");//设置拦截器拦截的请求路径( /** 表示拦截所有请求)
    }
}

4.3常见拦截路径设置

拦截路径 含义 举例
/* 一级路径 能匹配/depts,/emps,/login,不能匹配 /depts/1
/** 任意级路径 能匹配/depts,/depts/1,/depts/1/2
/depts/* /depts下的一级路径 能匹配/depts/1,不能匹配/depts/1/2,/depts
/depts/** /depts下的任意级路径 能匹配/depts,/depts/1,/depts/1/2,不能匹配/emps/1
posted @ 2025-07-17 21:20  mz456  阅读(18)  评论(0)    收藏  举报