当前位置: 首页 > article >正文

SpringBoot 实现登录功能

目录

  • 下发JWT 令牌
    • 依赖文件
    • 令牌生成
    • 令牌验证
  • 统一验证技术
    • 过滤器 Filter
      • 快速使用
      • 实现登录校验
    • 拦截器 Interceptor
      • 快速使用
      • 实现登录校验

下发JWT 令牌

全称: JSON Web Token

官网: https://jwt.io/

以JSON 的数据格式安全传输信息,利用 base64 进行编码。
在这里插入图片描述

组成:
第一部分:Header (头),记录 签名算法令牌类型
例如:{“alg”: “HS256”,“type”: “JWT”}

第二部分:Payload (有效载荷),携带自定义信息 ,一般为登录 账号 和 密码。

第三部分:Signature 防止 被篡改 将 header,payload,并加入指定密钥,通过指定签名算法计算而来。

依赖文件


 <dependency>
      <groupId>io.jsonwebtoken</groupId>
      <artifactId>jjwt</artifactId>
      <version>0.9.1</version>
    </dependency>

  <!--  java 9 以上需要引入  -->
     <dependency>
      <groupId>javax.xml.bind</groupId>
      <artifactId>jaxb-api</artifactId>
      <version>2.3.1</version>
    </dependency>
    <dependency>
      <groupId>org.glassfish.jaxb</groupId>
      <artifactId>jaxb-runtime</artifactId>
      <version>2.3.1</version>
    </dependency>

令牌生成

HashMap<String, Object> hashMap = new HashMap<>();
     hashMap.put("name", "lisi");
     hashMap.put("password", "1234");
String jwt = Jwts.builder()
/*sign 签名算法*/.signWith(SignatureAlgorithm.HS256, "ssstfthm")                   //sign  签名算法
/* 自定义内容 */ .setClaims(hashMap)                                              // 自定以内容
/*过期时间*/     .setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000))   
                 .compact(); //生成令牌
     
        System.out.println(jwt);

令牌验证

Claims :可以像遍历一个 Map 一样遍历 Claims 对象中的所有声明。例如,可以使用 for (Map.Entry<String, Object> entry : claims.entrySet()) 来遍历所有声明,并访问它们的键和值。

String token = "eyJhbGciOiJIUzI1NiJ9.eyJwYXNzd29yZCI6IjEyMzQiLCJuYW1lIjoibGlzaSIsImV4cCI6MTczNTQ4NzczMH0.JnQhXvsx0ZOsrPrtrUmkZ-RLCaVgwP8dgrS6nArF-vQ";
     Claims claims = Jwts.parser()
                         .setSigningKey("ssstfthm") //设置签名
                         .parseClaimsJws(token)     //令牌内容
                         .getBody();     
   
   System.out.println(claims);

在这里插入图片描述

统一验证技术

过滤器 Filter

JavaWeb 三大组件之一 (Servlet , Filter ,Listener) 之一

一般完成 通用的操作,比如:登录校验,统一编码,敏感字符处理

快速使用

多个 过滤器 按类名排序
1.创建过滤器类
javax.servlet.Filter

@WebFilter(urlPatterns = "/*")    //配置拦截路径
public class FilterDemo implements Filter {
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("过滤器创建");
        Filter.super.init(filterConfig);
    }

    @Override
    public void destroy() {
        System.out.println("过滤器销毁");
        Filter.super.destroy();
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("过滤器 拦截");

        //  放行操作
        filterChain.doFilter(servletRequest,servletResponse);
    }
}
  1. 在启动类中添加 @ServletComponentScan
org.springframework.boot.web.servlet.ServletComponentScan;

实现登录校验

在这里插入图片描述

@WebFilter(urlPatterns = "/*")
public class FilterDemo implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 1. 获取请求头
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        String url=request.getRequestURI();

        //2. 是登录请求直接放行
         if (url.contains("/login")) {
             filterChain.doFilter(servletRequest, servletResponse);
             System.out.println("登录操作合法");
             return;
         }


         //3. 获取请求头的令牌
           String jwt=request.getHeader("token");


        // 4.判断令牌是否存在,不存在返回错误
      if (!StringUtils.hasLength(jwt)) {
          //没有令牌 返回错误
          Result result=new Result(0,"NOT_LOGIN",null);

          //  手动转化  对象 --》json    阿里巴巴 fastjson
         String notlogin= JSONObject.toJSONString(result);
         response.getWriter().write(notlogin);
         return;
      }

      //5.解析token,解析失败返回错误结果
        try {
            JwtUtils.parseJWT(jwt);
        } catch (Exception e) {
            Result result=new Result(0,"NOT_LOGIN",null);
            String notlogin= JSONObject.toJSONString(result);
            response.getWriter().write(notlogin);
            return;
        }

        //6. 放行
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

拦截器 Interceptor

概念:是一种动态拦截方法调用的机制,类似于过滤器。Spring 框架中提供。

快速使用

1.定义拦截器,实现 HandlerInterfaceptor 接口

@Component   //交给IOC容器管理
public class LoginInterceptor implements HandlerInterceptor {
    @Override    //目标资源方法 运行前运行,   返回 true 放行     false,不放行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    @Override     // 运行后进行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override     // 最后运行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}
  1. 定义配置类

拦截路径:

拦截路径含义
/*一级路径
/**任意路径
/depts/*depts 下的一级路径
/depts/*depts 下的任意级路径

.excludePathPatterns(“/login”) 不需要拦截的资源

@Configuration    //配置类注解
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private LoginInterceptor loginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor).addPathPatterns("/**");
    }
}

实现登录校验

public class LoginInterceptor implements HandlerInterceptor {
    @Override    //目标资源方法 运行前运行,   返回 true 放行     false,不放行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器Q");
       String token=request.getHeader("token");
        if (!StringUtils.hasLength(token)) {
            //没有令牌 返回错误
            Result result=new Result(0,"NOT_LOGIN",null);

            //  手动转化  对象 --》json   阿里巴巴 fastjson
            String notlogin= JSONObject.toJSONString(result);
            response.getWriter().write(notlogin);
            return false;
        }

        try {
            JwtUtils.parseJWT(token);
        }catch (Exception e){
            String notlogin=JSONObject.toJSONString(new Result(0,"NOT_LOGIN",null));
           response.getWriter().write(notlogin);
           return false;
        }
        return true;
    }
}


http://www.kler.cn/a/461374.html

相关文章:

  • React 数据是怎样传递的
  • 用uniapp写一个播放视频首页页面代码
  • [实用指南]如何将视频从iPhone传输到iPad
  • Px4 V2.4.8飞控Mavlink命令控制说明
  • 【OpenCV】使用Python和OpenCV实现火焰检测
  • 算法-判断4的次幂
  • 书生·浦语大模型全链路开源体系-第9关 LMDeploy 量化部署进阶实践
  • TB1801D 线性驱动 LED 恒流芯片
  • 苹果系统MacOS下采用ObjectC访问opencv加载图片的一个简单实例
  • Flink的多流转换(分流-侧输出流、合流-union、connect、join)
  • 中华人民共和国网络安全法
  • BOE(京东方)“向新2025”年终媒体智享会落地深圳
  • 关于MCU复位电路的分析与设计
  • Java重要面试名词整理(十二):Netty
  • C++ Brain Teasers: 未指定和实现定义的行为-函数参数的求值顺序
  • 网络安全靶场合集:知识点与功能解析
  • 数据可视化-1:使用Matplotlib绘制多种图表
  • 手机租赁平台开发助力智能设备租赁新模式
  • 机器学习、深度学习、神经网络之间的关系
  • (推荐)【通用业务分发架构】1.业务分发 2.rpc调用 3.Event事件系统
  • win32汇编环境下,窗口程序中生成listview列表控件及显示
  • 深度学习day6|用pytorch实现VGG-16模型人脸识别
  • 2025跨年倒计时
  • qt5.15.2+visual studio2022 免安装版环境配置
  • Elasticsearch 入门教程
  • macos 支持外接高分辩率显示器开源控制软件