登录校验一

登录校验

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会后执行。

相关推荐
北邮刘老师7 分钟前
马斯克的梦想与棋盘:空天地一体的智能体互联网
数据库·人工智能·架构·大模型·智能体·智能体互联网
开开心心_Every9 分钟前
优化C盘存储:自定义软件文档保存路径工具
java·网络·数据库·typescript·word·asp.net·excel
多则惑少则明9 分钟前
AI大模型实用(八)Java快速实现智能体整理(使用LangChain4j-agentic来进行情感分析/分类)
java·人工智能·spring ai·langchain4j
qq_3771123711 分钟前
JAVA的平凡之路——此峰乃是最高峰JVM-GC垃圾回收器(2)-06
java·开发语言·jvm
用户21903265273516 分钟前
别再到处try-catch了!SpringBoot全局异常处理这样设计
java·spring boot·后端
醉舞经阁半卷书116 分钟前
Etcd服务端参数详解
数据库·etcd
李少兄18 分钟前
深入理解 Java Web 开发中的 HttpServletRequest 与 HttpServletResponse
java·开发语言·前端
gugugu.20 分钟前
Redis持久化机制详解(一):RDB全解析
数据库·redis·缓存
用户21903265273528 分钟前
SpringBoot自动配置:为什么你的应用能“开箱即用
java·spring boot·后端
爱笑的眼睛1128 分钟前
TensorFlow Hub:解锁预训练模型的无限可能,超越基础分类任务
java·人工智能·python·ai