登录校验一

登录校验

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

相关推荐
身如柳絮随风扬5 小时前
Java中的CAS机制详解
java·开发语言
qq_192779876 小时前
高级爬虫技巧:处理JavaScript渲染(Selenium)
jvm·数据库·python
风筝在晴天搁浅6 小时前
hot100 78.子集
java·算法
u0109272716 小时前
使用Plotly创建交互式图表
jvm·数据库·python
爱学习的阿磊6 小时前
Python GUI开发:Tkinter入门教程
jvm·数据库·python
故事和你917 小时前
sdut-Java面向对象-06 继承和多态、抽象类和接口(函数题:10-18题)
java·开发语言·算法·面向对象·基础语法·继承和多态·抽象类和接口
tudficdew7 小时前
实战:用Python分析某电商销售数据
jvm·数据库·python
TM1Club7 小时前
AI驱动的预测:新的竞争优势
大数据·人工智能·经验分享·金融·数据分析·自动化
zhang133830890757 小时前
CG-09H 超声波风速风向传感器 加热型 ABS材质 重量轻 没有机械部件
大数据·运维·网络·人工智能·自动化
sjjhd6528 小时前
Python日志记录(Logging)最佳实践
jvm·数据库·python