13---SpringBoot整合JWT,实现登录和拦截

news2024/12/24 11:34:21

1、 JWT简介

  1. 什么是JWT?
  • JWT(JSON Web Token)是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。
  • 它将用户信息加密到token里,服务器不保存任何用户信息。服务器通过使用保存的密钥验证token的正确性,只要正确即通过验证;应用场景如用户登录。
  1. 为什么使用JWT?

随着技术的发展,分布式web应用的普及,通过session管理用户登录状态成本越来越高,因此慢慢发展成为token的方式做登录身份校验,然后通过token去取redis中的缓存的用户信息,随着之后jwt的出现,校验方式更加简单便捷化,无需通过redis缓存,而是直接根据token取出保存的用户信息,以及对token可用性校验,单点登录更为简单。

  1. 传统Cookie+Session与JWT对比

① 在传统的用户登录认证中,因为http是无状态的,所以都是采用session方式。用户登录成功,服务端会保证一个session,当然会给客户端一个sessionId,客户端会把sessionId保存在cookie中,每次请求都会携带这个sessionId。

cookie+session这种模式通常是保存在内存中,而且服务从单服务到多服务会面临的session共享问题,随着用户量的增多,开销就会越大。而JWT不是这样的,只需要服务端生成token,客户端保存这个token,每次请求携带这个token,服务端认证解析就可。

JWT方式校验方式更加简单便捷化,无需通过redis缓存,而是直接根据token取出保存的用户信息,以及对token可用性校验,单点登录,验证token更为简单。

  1. JWT的组成(3部分)

第一部分为头部(header),第二部分我们称其为载荷(payload),第三部分是签证(signature)。【中间用 . 分隔】

一个标准的JWT生成的token格式如下:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI1IiwiaWF0IjoxNTY1NTk3MDUzLCJleHAiOjE1NjU2MDA2NTN9.qesdk6aeFEcNafw5WFm-TwZltGWb1Xs6oBEk5QdaLzlHxDM73IOyeKPF_iN1bLvDAlB7UnSu-Z-Zsgl_dIlPiw

2、SpringBoot整合JWT

  1. 导入依赖
<!--JWT-->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>4.2.1</version>
        </dependency>
  1. JwtInterceptor.java
public class JwtInterceptor implements HandlerInterceptor {
    @Autowired
    private UserService userService;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)  {
        String token = request.getHeader("token");
        //如果不是映射到方法直接通过
        if (!(handler instanceof HandlerMethod)){
            return true;
        }
        //执行认证
        if (StrUtil.isBlank(token)){
            throw new ServiceException(Constants.CODE_401,"无token,请重新登录!");
        }
        //获取token中的userId
        String userId;
        try{
            userId= JWT.decode(token).getAudience().get(0);
        }catch (JWTDecodeException j){
            throw new ServiceException(Constants.CODE_401,"token验证失败,请重新登录!");
        }
        //根据token中的userId查询数据库
        User user=userService.getById(userId);
        if (user==null){
            throw new ServiceException(Constants.CODE_401,"用户不存在,请重新登录!");
        }

        //用户密码加签验证token
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
        try{
            jwtVerifier.verify(token);  //验证token
        }catch (JWTVerificationException e){
            throw new  ServiceException(Constants.CODE_401,"token验证失败,请重新登录!");
        }


        return true;
    }
}
  1. InterceptorConfig.java
@Configuration
public class InterceptorConfig implements WebMvcConfigurer{
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
       registry.addInterceptor(jwtInterceptor())
               .addPathPatterns("/**")
               .excludePathPatterns("/user/login","/user/register","/**/export","/**/import");  //拦截除登录注册、导入导出以外请求,通过判断token是否合法来决定是否需要登录
    }

    @Bean
    public JwtInterceptor jwtInterceptor(){
        return new JwtInterceptor();
    }
}

  • 设置拦截器,需要拦截的路径等
  1. TokenUtils.java
@Component
public class TokenUtils {
    private static UserService staticUserService;

    @Autowired
    private UserService userService;

    @PostConstruct
    public void setUserService(){
        staticUserService=userService;
    }


    public static String genToken(String userId,String  sign){
        return JWT.create().withAudience(userId)  //将userId 保存到token里面,作为载荷
                .withExpiresAt(DateUtil.offsetHour(new Date(),2))//2小时后token过期
                .sign(Algorithm.HMAC256(sign)); //以sign作为token的密钥



    }

    //获取当前登录的用户信息
    public static User getCurrentUser(){
       try{
           HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
           String token = request.getHeader("token");
           if (StrUtil.isNotBlank(token)){
               String userId = JWT.decode(token).getAudience().get(0);
               return staticUserService.getById(Integer.valueOf(userId));
           }
       }catch (Exception e){
           return null;

       }
       return null;
    }
}

这样就在SpringBoot中整合好了JWT

3、前端测试接口

  1. 和之前登录相比,需要改造一下,因为现在是会生成一个token登录

request.js

import axios from 'axios'
import ElementUI from 'element-ui';

const request = axios.create({
	baseURL: 'http://localhost:8081',  
    timeout: 5000
})

// request 拦截器
// 可以自请求发送前对请求做一些处理
// 比如统一加token,对请求参数统一加密
request.interceptors.request.use(config => {
    config.headers['Content-Type'] = 'application/json;charset=utf-8';
    let user = localStorage.getItem("user")? JSON.parse(localStorage.getItem("user")):null
    if(user){
        config.headers['token'] = user.token;  // 设置请求头

    }
 
    return config
}, error => {
    return Promise.reject(error)
});

// response 拦截器
// 可以在接口响应后统一处理结果
request.interceptors.response.use(
    response => {
        let res = response.data;
        // 如果是返回的文件
        if (response.config.responseType === 'blob') {
            return res
        }
        // 兼容服务端返回的字符串数据
        if (typeof res === 'string') {
            res = res ? JSON.parse(res) : res
        }
        //当权限验证不通过的时候给出提示
        if(res.code==='401'){
            ElementUI.Message({
                message: res.msg,
                type:'error'
            });

        }
        return res;
    },
    error => {
        console.log('err' + error) // for debug
        return Promise.reject(error)
    }
)


export default request


  1. 测试登录
  • 未登录时直接进入首页

在这里插入图片描述

获取不到用户数据,并会弹出 无token,请重新登录

  • 登录账号后,进入首页

在这里插入图片描述

可以拿到数据,并且我们打开检查,看network里,刚才发送的请求里面,header中是有token的

在这里插入图片描述

退出登录或者删除token,便查不到数据,只有token匹配成功才能拿到完整数据。这就是用JWT做的登录和拦截。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在Ubuntu上安装Azure DevOps代理程序

Contents1 概述2. 安装Ubuntu 18.04操作系统3. 安装Azure DevOps Server 代理3.1 安装Azure DevOps Server 代理3.2 以服务方式运行代理1. 概述Ubuntu是一个以桌面应用为主的Linux操作系统&#xff0c;目前在不适用微软Windows的企业中&#xff0c;ubuntu被广泛应用在个人电脑中…

网络原理4 数据链路层

文章目录mac地址网络原理的总结在数据链路层中&#xff0c;最主要的就是以太网协议这里的目的IP和原地址都是mac地址 mac地址 首先要知道什么是Mac地址&#xff0c;mac地址也叫做物理地址或以太网地址&#xff0c;它是一个用来确认网络设备位置的位置&#xff0c;一个网卡就会…

javaWeb——第一章概述

目录 1.1 软件的分类 1.2 软件架构 1.3 web软件 1.4 web程序 web服务器&#xff1a; Tomcat: 扩展 Java web就是窗口和程序之间的交互&#xff1a; 1.1 软件的分类 系统软件 应用软件 介于两者之间的中间件&#xff08;插件&#xff09; 1.2 软件架构 B/S 服务器与浏…

ZC706P+ADRV9009连接RADIOVERSE详解之三

做好SD卡映像&#xff0c;连接好硬件之后&#xff0c;我们就可以尝试软件操作了。 步骤1&#xff1a;设置好网络 打开软件界面我们看到&#xff0c;板子默认的地址为192.168.1.10 端口号为55555.我们一定也设置跟板子连接的以太网口处于192.168.1网段&#xff0c;并且子网掩码…

【ESP32+freeRTOS学习笔记-(四)任务调度机制】

目录1 、什么是任务的调度机制1.1 概念1.2 三种算法1.3 决定算法的宏2、基本词条解释3、调度算法解释3.1 具有时间片的优先级抢先调度 Prioritized Pre-emptive Scheduling with Time Slicing3.1.1 图解高优先级任务抢占低优先级任务3.1.2 图解具有时间片的优先级抢占3.1.3 总结…

如何通过少量样本推断整体业务情况

在产品运营中非常常见&#xff0c;为了能够解决大量数据时分析效率急剧下降的窘况&#xff0c;我们就必须能够去分析非常小量样本的特征&#xff0c;再用这些特征去评估海量总体数据的特征&#xff0c;我们叫它样本检验。 样本&#xff0c;是指我们需要“分析或考察的数据”的…

MAC(m1)-安装Redis6.2.8

Redis官网&#xff1a;Download | Redis 我准备下载7以前的版本 下载放到如下位置 在这个目录打开终端&#xff1a; 编译测试&#xff0c;执行命令&#xff1a;sudo make test 等待了好久&#xff0c;估计好几分钟 最后出现&#xff1a; 下面准备安装redis&#xff0c;编译安…

计算机网络的定义和性能指标

目录计算机网络的定义计算机网络的分类计算机网络的性能指标速率带宽吞吐量时延时延带宽积往返时间利用率丢包率计算机网络的定义 计算机网络的精确定义并未统一&#xff1b;计算机网络的最简单的定义是&#xff1a;一些互相连接的、自治的计算机的集合&#xff1b; 互连&…

Kubernetes组件_Scheduler_02_二次调度

文章目录一、前言二、二次调度/运行期间调度Descheduler2.1 机器上安装helm2.2 每个机器都要准备好镜像2.3 使用helm部署三、Descheduler需要注意的点(相关理论知识)3.1 descheduler 调度策略3.2 descheduler 有哪些不足3.2.1 基于 Request 计算节点负载并不能反映真实情况3.2.…

【Lua】xLua逻辑热更新

1 前言 Lua基础语法 中系统介绍了 Lua 的语法体系&#xff0c;ToLua逻辑热更新 中介绍了 ToLua 的应用&#xff0c;本文将进一步介绍 Unity3D 中基于 xLua 实现逻辑热更新。 逻辑热更新是指&#xff1a;在保持程序正常运行的情况下&#xff0c;在后台修改代码逻辑&#xff0c;修…

子查询+「EXISTS」 以及 组合查询UNION ALL

目录方便的子查询及EXISTS使用子查询作为计算手段使用子查询过滤数据&#xff08;IN&#xff09;使用子查询过滤数据&#xff08;EXISTS&#xff09;组合查询UNION ALL如何使用UNION ALL合并多个结果集如何使用UNION去除集合的重复记录如何合并2个以上的结果集&#xff1f;方便…

Hudi(6):Hudi集成Spark之spark-shell 方式

目录 0. 相关文章链接 1. 启动 spark-shell 2. 插入数据 3. 查询数据 3.1. 转换成DF 3.2. 查询 3.3. 时间旅行查询 4. 更新数据 5. 增量查询 5.1. 重新加载数据 5.2. 获取指定beginTime 5.3. 创建增量查询的表 5.4. 查询增量表 6. 指定时间点查询 7. 删除数据 …

Python学习基础笔记六十二——反射2

1、 isinstanace(obj, cls) # 检查是否obj是否是类cls的对象&#xff1a; class Foo(object):passobj Foo()print(isinstance(obj, Foo)) 结果返回&#xff1a;True。 issubclass(sub, super) # 检查sub类是否是 super 类的派生类 class Foo(object):passclass Bar(F…

python详解(5)——类,类,还是类

目录 &#x1f3c6;一、前言 &#x1f3c6;二、类 &#x1f6a9;1、面向对象到底是什么 &#x1f6a9;2、数据成员and访问&#xff0c;汉堡店大升级&#xff08;超难&#xff09; &#x1f44d;①、类变量&#xff08;超难&#xff09; &#x1f44d;②、实例变量 &#x1f6a9…

A Latent Transformer for Disentangled Face Editing in Images and Videos翻译

点击下载论文 代码地址 图1 我们将真实图像投影到StyleGAN生成器的潜空间&#xff0c;并在编码的潜码上实现连续的解纠缠属性编辑。从原始图像和投影图像中&#xff0c;我们可以连续编辑一系列属性&#xff0c;例如&#xff1a;“微笑”、“刘海”、“拱形眉毛”、“年龄”、…

分布式对象存储设计原理

保存像图片、音视频这类大文件就是对象存储。不仅有很好的大文件读写性能&#xff0c;还可通过水平扩展实现近乎无限容量&#xff0c;并兼顾服务高可用、数据高可靠。 对象存储“全能”&#xff0c;主要因&#xff0c;对象存储是原生分布式存储系统&#xff0c;相对于MySQL、R…

[Linux]yum安装工具和vim编辑器

&#x1f941;作者&#xff1a; 华丞臧. &#x1f4d5;​​​​专栏&#xff1a;【LINUX】 各位读者老爷如果觉得博主写的不错&#xff0c;请诸位多多支持(点赞收藏关注)。如果有错误的地方&#xff0c;欢迎在评论区指出。 推荐一款刷题网站 &#x1f449; LeetCode刷题网站 文…

每日一问-ChapGPT-20230101-关于新年的规划

文章目录每日一问-ChapGPT系列起因每日一问-ChapGPT-20230101-关于新年的规划优秀的人&#xff0c;新年之初做哪些规划疫情时代&#xff0c;如何更好的保护好自己有哪些运动可以提升抵抗力冥想的具体实现步骤为什么制定了年度规划但往往完成不了如何克服看手机刷视频的习惯当日…

聊聊八卦,当年的顶流明星事件是如何把公司的缓存架构“击垮”的?

V-xin&#xff1a;ruyuan0330 获得600页原创精品文章汇总PDF 目录 一、为什么要用缓存集群二、20万用户同时访问一个热点缓存的问题三、基于流式计算技术的缓存热点自动发现四、动加载为JVM本地缓存五、限流熔断保护六、总结 一、为什么要用缓存集群 这篇文章&#xff0c;咱…

数值优化之基本概念

本文ppt来自深蓝学院《机器人中的数值优化》 目录 1 推荐书单 2 优化问题的基本范式 3 数值优化在机器人领域的应用 1 推荐书单 对于英语阅读有困难的同学可以看第一本书&#xff0c;对于最优化的介绍也是比较详细的。 这是第一本书的ppt链接最优化&#xff1a;建模、算法…