SpringBoot整合jwt(小白入门)

本文项目所用版本为: https://blog.csdn.net/weixin_39570751/article/details/133386557

代码仓库: https://gitee.com/skyblue0678/springboot-demo

目录

什么是JWT

JWT依赖

写一个jwt工具类

测试一下jwt

优化:将过期时间配置在文件中

答疑:反正都能解析,加密有啥用?


什么是JWT

JWT(JSON Web Token)是一种用于身份验证和授权的开放标准(RFC 7519),它是一种安全的、轻量级的身份验证方式。JWT由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。

头部通常由两部分信息组成:令牌的类型(即JWT)和所使用的签名算法。载荷包含了一些声明(Claim),用于描述用户信息、权限、过期时间等。签名由头部和载荷组成,并使用密钥进行加密生成。

JWT的使用流程如下:用户使用用户名和密码进行登录,服务器验证用户信息是否正确。服务器生成一个JWT,将用户信息、权限等信息写入载荷中,并使用密钥对头部和载荷进行签名。服务器将生成的JWT返回给客户端,客户端将其存储在本地,通常是在浏览器的cookie或本地存储中。客户端在后续的请求中,将JWT作为请求头部或请求参数传递给服务器。服务器收到请求后,验证JWT的签名是否正确,如果正确则解析出用户信息、权限等信息,进行后续操作。

JWT的优点如下:

无状态:JWT是无状态的,服务器不需要保存任何会话信息,可以轻松扩展和分布式环境下使用。

安全:JWT通过密钥对头部和载荷进行签名,保证了数据的完整性和安全性。

跨域支持:JWT可以跨域使用,可以在不同的域名和服务器之间使用。

简单易用:JWT使用简单,易于实现和维护。

然而,JWT也存在一些缺点:

载荷信息不能太多:JWT的载荷信息不能太多,否则会导致JWT的长度过长,增加网络传输的负担。

安全性依赖于密钥:JWT的安全性依赖于密钥的保护,如果密钥泄露,则JWT的安全性将受到威胁。

无法撤销:一旦JWT生成后,无法撤销,除非修改密钥或者设置短期的过期时间。

JWT依赖

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.19.0</version>
</dependency>

将这一段拷贝到pom.xml即可。

写一个jwt工具类

jwt主要就两个方面,一个生成token,一个校验和解析token。

/**
 * jwt工具类
 */
@Component
public class JWTUtil {

    @Resource
    UserService userService;

    /**
     * 创建jwt
     * @param user
     * @return
     */
    public String createToken(User user){
        return JWT.create().withAudience(user.getId().toString()) // 设置载荷
                .withExpiresAt(DateUtil.offsetHour(new Date(), 24)) // 设置签名过期的时间:24小时后
                .sign(Algorithm.HMAC256(user.getPwd())); // 签名 Signature
    }

    /**
     * 校验Token,返回用户信息
     * @param token
     * @return
     */
    public User verify(String token){
        DecodedJWT decode = JWT.decode(token);
        String userId = decode.getAudience().get(0);
        User user = userService.getById(userId);
        //获取校验器
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPwd())).build();
        jwtVerifier.verify(token);
        return user;
    }
}

测试一下jwt

首先,我们写一个根据token获取User的接口。

@GetMapping("/jwt/test")
public User jwtTest(HttpServletRequest request){
    String token = request.getHeader("Token");
    User user = jwtUtil.verify(token);
    return user;
}

然后,改写login方法生成一下Token:

@GetMapping("/jwt/login")
public String jwtLogin(String username,String password){
    User user = userService.getByUsername(username);
    if(Objects.nonNull(user)) {
        if (!user.getPwd().equals(password)) {
            return "密码错误!";
        }
    }
    String token = jwtUtil.createToken(user);
    return token;
}

用postman发登录接口

得到Token:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiIxIiwiZXhwIjoxNzAzNTU5MjIzfQ.QFGXF6ZkQjmUtVEuDb8c1h_tFHAXE7G_WaSOuOkeBAA

再把Token放到Header,发测试接口:

成功了。

优化:将过期时间配置在文件中

我们目前过期时间是写死的,这样并不好,属于硬编码了。更恰当的方法是写在yml配置文件,或者Apollo中。

现在我们项目没有用Apollo,我们就改成配置文件吧。

在JwtUtil中添加配置:

@Value("${jwt.expire.offset:}")
Integer expireOffset;

yml中:

代码:

jwt:
  expire:
    offset: 30

单位是秒,所以创建Token的地方也改下:

public String createToken(User user){
    return JWT.create().withAudience(user.getId().toString()) // 设置载荷
            .withExpiresAt(DateUtil.offsetSecond(new Date(), expireOffset)) // 设置签名过期的时间
            .sign(Algorithm.HMAC256(user.getPwd())); // 签名 Signature
}

如果过期了,后台会报错,比如: com.auth0.jwt.exceptions.TokenExpiredException: The Token has expired on Mon Dec 25 11:10:33 CST 2023.

答疑:反正都能解析,加密有啥用?

已知在JWT的处理过程中,密钥(本项目中使用的密钥是password)在签名和验证阶段都起着关键作用。

对于DecodedJWT decode = JWT.decode(token);这行代码,实际上只是将JWT字符串解析为一个可操作的对象,并没有进行签名的验证。在这个阶段,确实不需要密钥。

但是,当你想要验证这个token的签名是否有效时,就需要使用到密钥了。例如,在代码中的这部分:

JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPwd())).build();
jwtVerifier.verify(token);

总结一下,虽然JWT.decode(token)本身不需要密钥,但要确保JWT的有效性和真实性(比如过期时间),验证签名的过程是必要的,而这确实需要使用到密钥。

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

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

相关文章

mysql根据条件修改字段

数据 sql语句 根据field2 字段情况&#xff0c;修改field1字段 update t1 tt1 set tt1.field1 ( case when tt1.field2 in (我家2) then 1111 when tt1.field2 in (你的家11) then 2222 else tt1.field2 end )结果

ros2+python,报错:`GLIBCXX_3.4.30‘ not found

在执行代码import rclpy&#xff0c;出现如下图所示报错 如报错信息所示&#xff0c;/home/shui/miniconda3/envs/ros2/bin/…/lib/libstdc.so.6中没有找到GLIBCXX_3.4.30’ 检查/home/shui/miniconda3/envs/ros2/bin/…/lib/的libstdc.so.6文件 cd /home/shui/miniconda3/e…

7. Resource database in UVM(UVM的资源数据库)

UVM集中资源数据库用于存储可配置&#xff08;configurable&#xff09;对象/object、变量/variables、虚拟接口/virtual interfaces、队列/queues、类句柄/class handles等&#xff0c;并从数据库中检索它们。这种可配置的测试平台为验证工程师提供了一定程度的自由度&#xf…

sqlmap各个命令的解释及其基本用法

各个命令的用法 -h,--help Show basic help message and exit(显示基本帮助消息并退出) -hh Show advanced help message and exit&#xff08;显示高级帮助信息并退出&#xff09; --version Show programs version number and exit&#xff08;显示程序的版本…

【Vue UI组件库】

Vue UI组件库 1 移动端常用UI组件库2 PC端常用UI组件库2.1 Element UI 1 移动端常用UI组件库 Vant&#xff1a;https://youzan.github.io/vantCube UI&#xff1a;https://didi.github.io/cube-uiMint UI&#xff1a;http://mint-ui.github.io 2 PC端常用UI组件库 Element U…

带你学C语言~指针(3)

目录 ✍0.前言 &#x1f680;1.字符指针变量 &#x1f685;2.数组指针变量 &#x1f431;‍&#x1f3cd;2.1.数组指针变量是什么 &#x1f431;‍&#x1f3cd;2.2数组指针变量怎么初始化 &#x1f6a2;3.二维数组传参的本质 &#x1f680;4.函数指针变量 ✈4.1函数指…

Ubuntu-22.04编译安装FLTK

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、FLTK是什么&#xff1f;二、下载源代码三、准备编译环境四、编译五、运行测试程序六、Demo总结 前言 最近在研究FLTK&#xff0c;突然对它感了兴趣&#x…

猫粮选择困难?5款性价比高的主食冻干品牌推荐

近年来&#xff0c;冻干猫粮作为热门的高品质猫粮&#xff0c;受到了许多追求纯天然、健康食品的铲屎官的关注。萌新铲屎官就很疑惑了冻干猫粮可以代替猫粮作为主食吗&#xff1f;冻干猫粮真就那么好吗&#xff1f; 那么今天作为一个宠物店店长&#xff0c;跟大家一起聊聊各种…

UG模型的显示与隐藏

在UG中&#xff0c;除了通过图层的方式控制模型的显示与隐藏外&#xff0c;还可以直接通过显示与隐藏命令&#xff0c;位置在菜单-编辑-显示与隐藏&#xff0c;需要注意的是这些命令只能对可视图层中的模型进行控制 显示与隐藏&#xff1a;ctrl w 可以通过模型的类别&#xf…

系统架构设计师笔记

第1章计算机组成与体系结构 1.1.1计算机硬件的组成 &#xff08;1&#xff09;控制器。控制器是分析和执行指令的部件&#xff0c;也是统一指挥并控制计算机各部件协调工作的中心部件&#xff0c;所依据的是机器指令。控制器的组成包含如下。 ①程序计数器PC&#xff1a;存储下…

忻府区政协主席郭新和带队视察洁晋发电环保教育基地中国流动科技博物馆展厅

忻府区政协主席郭新和带队视察洁晋发电环保教育基地中国流动科技博物馆展厅 2023年12月5日&#xff0c;忻府区政协主席郭新和带队视察中国流动科技博物馆展览情况。 郭新和一行来到位于忻州市洁晋发电有限公司环保教育基地的中国流动科技馆忻府区展厅。展厅内配备了科普知识展…

2023 年备受瞩目的向量数据库赛道盘点出炉

近日&#xff0c;Zilliz 捷报频传&#xff0c;先后斩获来自极客公园、量子位、界面科技、OSCHINA 等行业头部媒体所颁发的奖项以及荣登相应榜单。 接下来&#xff0c;就让我们一起来了解一下这些颇受业界认可的奖项及榜单&#xff5e; 2023 中国创新力量 50 榜单 【2023 中国创…

托盘在线缠绕机

托盘在线式缠绕机是适应流水线作业的包装机械&#xff0c;很适合现代化企业的自动化包装的需要&#xff0c;对提高包装效率&#xff0c;降低劳动强度&#xff0c;有效利用人力资源&#xff0c;起到较好的作用。目前&#xff0c;托盘在线缠绕机已经在化工、电子、食品、饮料、造…

小李的2023年度读书盘点

小李的2023年度读书盘点 主题读书 1、纪实文学 和去年一样&#xff0c;依然以上海译文出版社的“译文纪实”系列图书为主。该系列大部分图书质量说得过去&#xff0c;今年读的几本中&#xff0c;一本不及格&#xff08;3/5星以下&#xff09;&#xff0c;《打工女孩》&#…

Facebook企业户与个人户的区别是什么?一文带你看懂Facebook企业户!

Facebook 作为最大的社交平台之一&#xff0c;吸引了大多数的卖家进行投放广告&#xff0c;并且投放广告的效果也是很不错的。Facebook个人账户大家都不陌生&#xff0c;那么 Facebook 有企业户吗&#xff1f;当然是有的&#xff0c;Facebook 有针对企业和品牌的专门广告账户&a…

10 种最佳排序算法原理及代码

什么是排序算法? 从本质上讲&#xff0c;排序算法是一种计算机程序&#xff0c;它将数据组织成特定的顺序&#xff0c;例如字母顺序或数字顺序&#xff0c;通常是升序或降序。 排序算法能干啥? 排序算法主要用于以有效的方式重新排列大量数据&#xff0c;以便更容易地进行搜…

围栏中心点

后端返回的数据格式是 [{height: 0,lat: 30.864277169098443,lng:114.35252972024682}{height: 1,lat: 30.864277169098443,lng:114.35252972024682}.........]我们要转换成 33.00494857612568,112.53886564762979;33.00307854503083,112.53728973842954;33.00170296814311,11…

MySQL日期查询 今天、明天、本月、下月、星期、本周第一天、本周最后一天、本周七天日期

文章目录 今天日期明天日期本月第一天本月最后一天下个月第一天当前月已过几天当前月天数当前月所有日期获取星期本周第一天本周最后一天获取本周的七天日期今天日期 select curdate()明天日期 select DATE_SUB(curdate(),INTERVAL -1 DAY) AS tomorrow本月第一天 select da…

阿春的450MT售价提前大曝光,符合你的预期吗?

最新消息&#xff0c;阿春的450MT在国外的官网上已经曝光&#xff0c;售价8990澳元&#xff0c;折合RMB 4.35万元&#xff0c;毕竟对他们来说这也是进口车嘛。那么从这个售价可以看出一些端倪&#xff0c;同平台的450SR海外售价8290澳元&#xff0c;450MT和450SR差价700澳元&am…

UI自动化测试的痛点

当我们找工作的时候查看招聘信息发现都需要有自动化测试经验&#xff0c;由此看来测试人员不会一点自动化测试技术都不好意思说自己是做软件测试的。大部分测试人员也都是从使用自动化测试工具、录制回放、测试脚本、开发小工具入门自动化测试的&#xff0c;然后在慢慢的接触 U…