登录校验一

登录校验

JWT令牌

  • 引入依赖

    XML 复制代码
    <!-- JWT依赖-->
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.9.1</version>
    </dependency>

    在引入完JWT来赖后,就可以调用工具包中提供的API来完成JWT令牌的生成和校验。工具类:Jwts

  • 引入JWT工具类:在项目工程下创建 com.itheima.util 包,并把提供JWT工具类复制到该包下

    java 复制代码
    package com.itheima.util;
    
    import io.jsonwebtoken.Claims;
    import io.jsonwebtoken.Jwts;
    import io.jsonwebtoken.SignatureAlgorithm;
    
    import java.util.Date;
    import java.util.Map;
    
    public class JwtUtils {
    
        private static String signKey = "SVRIRUlNQQ==";
        private static Long expire = 43200000L;
    
        /**
         * 生成JWT令牌
         * @return
         */
        public static String generateJwt(Map<String,Object> claims){
            String jwt = Jwts.builder()
                    .addClaims(claims)
                    .signWith(SignatureAlgorithm.HS256, signKey)
                    .setExpiration(new Date(System.currentTimeMillis() + expire))
                    .compact();
            return jwt;
        }
    
        /**
         * 解析JWT令牌
         * @param jwt JWT令牌
         * @return JWT第二部分负载 payload 中存储的内容
         */
        public static Claims parseJWT(String jwt){
            Claims claims = Jwts.parser()
                    .setSigningKey(signKey)
                    .parseClaimsJws(jwt)
                    .getBody();
            return claims;
        }
    }
  • 完善 EmpServiceImpl中的 login 方法逻辑, 登录成功,生成JWT令牌并返回

    java 复制代码
    @Override
    public LoginInfo login(Emp emp) {
        Emp empLogin = empMapper.getUsernameAndPassword(emp);
        if(empLogin != null){
            //1. 生成JWT令牌
            Map<String,Object> dataMap = new HashMap<>();
            dataMap.put("id", empLogin.getId());
            dataMap.put("username", empLogin.getUsername());
            
            String jwt = JwtUtils.generateJwt(dataMap);
            LoginInfo loginInfo = new LoginInfo(empLogin.getId(), empLogin.getUsername(), empLogin.getName(), jwt);
            return loginInfo;
        }
        return null;
    }

过滤器Filter

过滤器的基本使用操作:

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

  • 第2步,配置过滤器:Filter类上加 @WebFilter 注解 ,配置拦截资源的路径(指定属性urlPatterns)引导类上加 @ServletComponentScan 开启Servlet组件支持。

    拦截路径:

    |--------|--------------|-----------------------|
    | 拦截路径 | urlPatterns值 | 含义 |
    | 拦截具体路径 | /login | 只有访问 /login 路径时,才会被拦截 |
    | 目录拦截 | /emps/* | 访问/emps下的所有资源,都会被拦截 |
    | 拦截所有 | /* | 访问所有资源,都会被拦截 |

org.example.filter 包下创建TokenFilter:

java 复制代码
package org.example.filter;

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.example.utils.JwtUtils;

import java.io.IOException;

@Slf4j
@WebFilter(urlPatterns = "/*")
public class TokenFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        //1、获取请求路径
        String requestURI = request.getRequestURI();

        //2、判断是否是登录请求(login)放行
        if(requestURI.contains("/login")){
            log.info("登录请求,放行");
            filterChain.doFilter(request,response);
            return;
        }

        //3、获取请求头token
        String token = request.getHeader("token");

        //4、判断token是否存在,如果不存在说明没有用户登录,返回错误信息(响应401状态码)
        if(token == null || token.isEmpty()){
            log.info("令牌为空,响应401");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return;
        }

        //5、如果token存在,校验令牌,如果校验失败,返回错误信息(响应401状态码)
        try{
            JwtUtils.parseJWT(token);
        }catch (Exception e){
            log.info("令牌非法,响应401");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return;
        }

        //6、校验通过,放行
        log.info("令牌合法,放行");
        filterChain.doFilter(request,response);
    }
}

过滤器链上过滤器的执行顺序:注解配置的Filter,优先级是按照过滤器类名(字符串)的自然排序。 比如:

  • AbcFilter

  • DemoFilter

这两个过滤器来说,AbcFilter 会先执行,DemoFilter会后执行。

相关推荐
m0_748554812 小时前
golang如何实现用户订阅偏好管理_golang用户订阅偏好管理实现总结
jvm·数据库·python
lee_curry2 小时前
第四章 jvm中的垃圾回收器
java·jvm·垃圾收集器
早日退休!!!3 小时前
《数据结构选型指南》笔记
数据结构·数据库·oracle
@insist1233 小时前
信息安全工程师考点精讲:身份认证核心原理与分类体系(上篇)
大数据·网络·分类·信息安全工程师·软件水平考试
xcLeigh3 小时前
KES数据库性能优化实战
数据库·sql·性能优化·sql优化·数据性能
天辛大师3 小时前
AI助力旅游扩大化,五一旅游公园通游年票普惠研究
大数据·启发式算法·旅游
阿正呀3 小时前
Redis怎样实现本地缓存的高效失效通知
jvm·数据库·python
yoyo_zzm3 小时前
Laravel9.x新特性全解析
数据库·mysql·nginx
九转成圣3 小时前
Java 性能优化实战:如何将海量扁平数据高效转化为类目字典树?
java·开发语言·json
2501_901200533 小时前
mysql如何设置InnoDB引擎参数_优化innodb_buffer_pool
jvm·数据库·python