JavaEE——Spring Boot + jwt

目录

什么是Spring Boot + jwt?

如何实现Spring Boot + jwt:

1. 添加依赖

2、创建JWT工具类

3. 定义认证逻辑

4. 添加过滤器

 5、 http请求测试


什么是Spring Boot + jwt?

Spring Boot和JWT(JSON Web Token)是一对常见的组合,用于构建安全的Web应用程序。下面是它们的主要功能和如何结合使用的概览:

  1. Spring Boot:Spring Boot是一个用于快速构建基于Spring框架的Java应用程序的工具。它通过提供默认配置和约定大于配置的方式,简化了Spring应用程序的开发过程。

  2. JWT(JSON Web Token):JWT是一种开放标准(RFC 7519),用于在各方之间安全地传输信息。它由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。JWT通常用于身份验证和信息传输,在Web应用程序中广泛应用。

如何实现Spring Boot + jwt:

1. 添加依赖

① 在你的 Spring Boot 项目中添加 JWT 相关的依赖,比如 jjwt 库,以便于创建和验证 JWT。

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

② 确保mybatis、mysql、spring boot、redis、druid、lombok等相关依赖存在

③ maven 刷新下载依赖

2、创建JWT工具类

① 编写一个工具类来处理 JWT 的创建、解析和验证。这个类通常包含以下方法: - 创建 JWT:将用户信息(例如用户名、角色等)加密生成一个 token。

    public static String getToken(Map<String, Object> claims) {
        // JWT的签发时间
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        // 指定签名的时候使用的签名算法
        SignatureAlgorithm signatureAlgotithm = SignatureAlgorithm.HS256;
        long expMillis = nowMillis + 604800000L;        // 默认设置7天过期
        Date expirationDate = new Date(expMillis);
        String token = Jwts.builder()               // 创建jwt builder
                .setClaims(claims)                      // 必须放最前面,不然后面设置的东西都会没有:如setExpiration会没有时间
                .setId(UUID.randomUUID().toString())     // jwt唯一标识
                .setIssuedAt(now)                                    // 签发时间
                .setExpiration(expirationDate)                 // 过期时间
                .signWith(signatureAlgotithm, key)          // 设置签名实用的签名算法和使用的密钥
                .compact();
        return token;
    }

 ② 编写一个工具类来处理 JWT 的创建、解析和验证。这个类通常包含以下方法: - 解析 JWT:从收到的 token 中提取用户信息

  public static Claims parseJwt(String token) throws Exception {
      String msg = null;
      try{
          Claims claims = Jwts.parser()
                .setAllowedClockSkewSeconds(604800) // 允许7天的偏移
                .setSigningKey(key)                         // 设置签名密钥
                .parseClaimsJws(token).getBody(); // 设置需要解析的JWT
          return claims;
      }catch (SignatureException se) {
          msg = "密钥错误";
          log.error(msg, se);
          throw new RuntimeException(msg);
      }catch (MalformedJwtException me) {
          msg = "密钥算法或者密钥转换错误";
          log.error(msg, me);
          throw new RuntimeException(msg);

 }
catch (MissingClaimException mce) {
            msg = "密钥缺少校验数据";
            log.error(msg, mce);
            throw new RuntimeException(msg);

        }catch (ExpiredJwtException mce) {
            msg = "密钥已过期";
            log.error(msg, mce);
            throw new RuntimeException(msg);

        }catch (JwtException jwte) {
            msg = "密钥解析错误";
            log.error(msg, jwte);
            throw new RuntimeException(msg);
        }
    }

3. 定义认证逻辑

① 在 controller 中,添加 @Slf4j 注解用于日志记录

② 在 controller 中,创建一个 login方法用来控制用户登入

 @PostMapping("/login")
 public Map<String, Object> login(@RequestBody User user) {
     log.info("user",user);
     log.info("用户名: [{}]", user.getName());
     log.info("密码: [{}]", user.getPwd());
     User u = userService.login(user);
 }

③ 在 login中 创新一个Map对象,承载认证结果和相关信息

Map<String, Object> map = new HashMap<>();

④ 如果用户认证成功(u != null),则创建一个包含用户ID和名称的Map对象,并生成一个JWT令牌。接着在响应map中设置状态为true,消息为“认证成功”,并包含了生成的令牌。

⑤ 如果认证失败(u为空),则在响应map中设置状态为false,并包含了一个指示“用户名或者密码错误”的消息。 

try {
      if (u != null) {
            Map<String, Object> payLoad = new HashMap<>();
            payLoad.put("id", u.getId());
            payLoad.put("name", user.getName());
            String token = JWTUtils.getToken(payLoad);
            map.put("state", true);
            map.put("message", "认证成功");
            map.put("token",token);
        } else {
             map.put("state", false);
             map.put("message", "用户名或者密码错误");
         }
    } catch (Exception e) {
         map.put("state", false);
         map.put("msg", e.getMessage());
    }
    return map;

4. 添加过滤器

① 创建一个JWTInterceptor过滤器文件来检查传入的请求是否携带有效的 token,并根据需要进行相应的处理

public class JWTInterceptor implements HandlerInterceptor {

 ② 创建preHandle方法,在请求处理之前执行,用于检查传入的请求是否携带有效的 token,并解析令牌

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Map<String, Object> map = new HashMap<>();
        // 获取请求头中令牌
        String token = request.getHeader("token");
        if(!StringUtils.isEmpty(token)) {              
            try {
                Claims claims = JWTUtils.parseJwt(token); // 如果找到令牌就使用 JWTUtils.parseJwt() 方法解析令牌
                return true;                                     // 解析成功,即令牌有效,返回true
            } catch (RuntimeException e) {          // 如果解析失败,会捕获 RuntimeException 异常
                e.printStackTrace();
                map.put("msg", e.getMessage());  // map.put("msg","密钥错误!");
            }
        }

③ 将异常信息放入 map 中,并设置一些响应信息,然后将信息以 JSON 格式返回给客户端

        map.put("message","token为null,必须携带token");
        map.put("state",false);             // 设置状态
        // 将map 转为 json  jackson
        String json = new ObjectMapper().writeValueAsString(map);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println(json);
        return false;
    }
}

④ 再添加一个拦截器配置类 InterceptorConfig,用于配置和注册拦截器到 Spring MVC 中

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        String[] patterns = new String[] {"/auth/login","/*.html","/css/**","/js/**","/images/**","/layui/**"};    // 添加不拦截的方法
        registry.addInterceptor(new JWTInterceptor())
               .addPathPatterns("/**")         // 其他接口token验证
               .excludePathPatterns(patterns);  // 不进行token验证
    }
}

 5、 http请求测试

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/575345.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HarmonyOS hsp制作与引用

1. HarmonyOS hsp制作与引用 1.1 介绍 HSP动态共享包&#xff08;模块&#xff09;,应用内HSP指的是专门为某一应用开发的HSP&#xff0c;只能被该应用内部其他HAP/HSP使用&#xff0c;用于应用内部代码、资源的共享。应用内HSP跟随其宿主应用的APP包一起发布&#xff0c;与该…

阶跃星辰:探索智能科技的星辰大海

引言 在当今快速发展的科技时代&#xff0c;人工智能已经成为推动社会进步的重要力量。阶跃星辰&#xff0c;正是在这一背景下诞生的。 阶跃星辰是一家专注于通用人工智能探索的公司&#xff0c;成立于2023年4月。该公司的创始团队由一群对人工智能充满热情和渴望的人组成&am…

【Python】异常、模块与包

目录 捕获异常 异常的传递 Python中的模块 模块的导入方式 as定义别名 自定义模块 Python包 第三方包 综合案例 当我们的程序遇到了BUG, 那么接下来有两种情况: ① 整个程序因为一个BUG停止运行 ② 对BUG进行提醒, 整个程序继续运行 但是在真实工作中, 我们肯定不能…

快解析搭建网站解决方案

在如今网络时代下&#xff0c;各行各业都需要有自己的门户网站。 企业搭建自己的门户网站&#xff0c;有着众多实际意义: 1.可以全面详细地介绍企业及企业产品&#xff0c;这是企业网站的一个最基本的功能。企业可以把任何想让大众知道的信息放到网站&#xff0c;当人们想知道…

http忽略ssl认证

我们在发请求时&#xff0c;会遇到需要ssl证书验证的报错&#xff0c;针对该错误以及所使用的不同的创建连接的方式&#xff0c;进行ssl证书忽略 忽略SSL证书的流程 简介&#xff1a;需要告诉client使用一个不同的TrustManager。TrustManager是一个检查给定的证书是否有效的类…

pytest参数化数据驱动(数据库/execl/yaml)

常见的数据驱动 数据结构&#xff1a; 列表、字典、json串 文件&#xff1a; txt、csv、excel 数据库&#xff1a; 数据库链接 数据库提取 参数化&#xff1a; pytest.mark.parametrize() pytest.fixture()…

vue3.0项目中运用vant的以及移动端的适配

文章目录 概要移动端的适配vant的引入开发以及打包过程中遇到的问题 概要 在Vue-Vben-Admin项目中运用vant-ui实现部分页面支持手机端h5页面的预览 移动端的适配 适配的原理 自适应 根据不同的设备的屏幕大小来自动调整尺寸&#xff0c;大小响应式 会随着屏幕的变动而自动调整…

[实验]Keil 4下仿真三星2440A芯片的汇编及CPIO控制实验

一、安装Keil uVision4 (详细安装过程忽略) 点击finish完成安装 二、新建项目&#xff0c;导入项目文件 选择对应的芯片&#xff0c;此处我们选择三星的S3C2440A&#xff0c;点击OK 在Source Group 1处右键&#xff0c;点击Add Files to "Sourcce Group 1’…将下图…

每日一题(PTAL2-022 ):重排链表--排坑

它的测试数据有可能有分裂节点&#xff0c;所以需要计算实际所给链表的长度 #include<bits/stdc.h> using namespace std; struct Node{int val;int next; }x[100005]; int main(){int j0;int start;int n;int ad1,num,ad2;cin>>start>>n;for(int i0;i<n…

从 MySQL 到 ClickHouse 实时数据同步 —— Debezium + Kafka 表引擎

目录 一、总体架构 二、安装配置 MySQL 主从复制 三、安装配置 ClickHouse 集群 四、安装 JDK 五、安装配置 Zookeeper 集群 六、安装配置 Kafaka 集群 七、安装配置 Debezium-Connector-MySQL 插件 1. 创建插件目录 2. 解压文件到插件目录 3. 配置 Kafka Connector …

【机器学习-18】特征筛选:提升模型性能的关键步骤

一、引言 在机器学习领域&#xff0c;特征筛选是一个至关重要的预处理步骤。随着数据集的日益庞大和复杂&#xff0c;特征的数量往往也随之激增。然而&#xff0c;并非所有的特征都对模型的性能提升有所贡献&#xff0c;有些特征甚至可能是冗余的、噪声较大的或者与目标变量无关…

SpringBoot Aop使用篇

Getting Started SpringBoot AOP的实践 AOP相关的概念&#xff1a; Aspect&#xff08;切面&#xff09;&#xff1a; Aspect 声明类似于 Java 中的类声明&#xff0c;在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice。就是抽离出来的逻辑类&#xff0c;比如日志、权限…

《苍穹外卖》Day08部分知识点记录

一、useGeneratedKeys和keyProperty useGeneratedKeys和keyProperty是<insert>标签中的两个属性&#xff0c;用于处理自动生成的主键值。 1. useGeneratedKeys userGeneratedKeys"true"表示启用自动生成主键功能&#xff1b;当useGeneratedKeys设置为true时…

VScode使用cmake编译

一&#xff1a;输入 ctrlshiftp打开用于命令执行的输入框 二&#xff1a;输入cmake&#xff0c;选择quick start 模式 三&#xff1a;选择版本最高的gcc版本 四&#xff1a;输入项目名称 选择C 五&#xff1a;选择executable 这样便创建好了最简单的cmake例程&#xff0c;一个…

同态加密原理解析

目录 1.数学介绍2.使用多项式环进行加密2.1 私钥和公钥的产生2.2 加密2.3 解密 3.同态计算3.1 同态加法3.2 同态乘法 1.数学介绍 同态加密方案基于一个难以计算的问题Ring Learning with Errorsred。这些方案中的数据在加密和未加密时都用多项式表示。 这里举一个简单的多项式…

AWTK MODBUS Client channel 模型

名称&#xff1a;modbus_client_channel 功能&#xff1a;通过 modbus 协议访问远程 slave 设备上的数据&#xff0c;需要配合 modbus_client模型一起使用。用于将 modbus client 中的 channel 包装成view_model或者view_model_array 一般来说不需要&#xff0c;直接使用modbus…

docker常用基本命令

把jar包和 dockerfile文件放到同一目录下#构建Docker镜像 注意后面的 . 不能省略 docker build -t your-image-name .#运行并创建一个容器 docker run -d -p 8080:8080 --name container_name your-image-name# 停止容器 767fce4cb990 容器ID (容器名也可以) docker stop 767f…

柱形图“变个装”,跟上时尚步伐!

前言 职场中&#xff0c;日报、周报、月报、年度总结&#xff0c;都离不开图表的制作&#xff0c;而柱状图又是最常用的一种&#xff0c;怎样的柱状图&#xff0c;才能让领导更容易阅读&#xff0c;甚至是眼前一亮呢&#xff1f;今天小编就将为大家介绍一下如何借助葡萄城公司…

4月26日 阶段性学习汇报

1.毕业设计与毕业论文 毕业设计已经弄完&#xff0c;加入了KNN算法&#xff0c;实现了基于四种常见病的判断&#xff0c;毕业论文写完&#xff0c;格式还需要调整&#xff0c;下周一发给指导老师初稿。目前在弄答辩ppt&#xff08;25%&#xff09;。25号26号两天都在参加校运会…

六西格玛管理培训并未过气:深挖其现代价值与应用

在众多管理培训中&#xff0c;六西格玛管理培训因其卓越的成效和广泛的适用性而备受推崇。尽管有人认为六西格玛管理培训已经过时&#xff0c;但实际上&#xff0c;它在现代企业中仍具有不可忽视的价值和应用。深圳天行健六西格玛培训公司解析如下&#xff1a; 一、六西格玛管理…
最新文章