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

如何通过 JWT 来解决登录认证问题

1. 问题引入

在登录功能的实现中

传统思路:

  1. 登录页面时把用户名和密码提交给服务器
  2. 服务器验证用户名和密码,并把检验结果返回给后端
  3. 如果密码正确,则在服务器端创建 session,通过 cookie 把 session id 返回给浏览器

但是正常情况下一个 web 应用是部署到多个服务器上的,通过 Nginx 等进行负载均衡,此时就可能出现这样的情况:用户登录请求之后把 session 存储在了第一台服务器上,但是后续的请求操作,例如查询等,就可能会转发到第二台服务器上,但是第二台服务器没有存储该用户的 session,就会让用户重新登录,这肯定是不合理的

解决方案:

  1. 对于服务端来说,上述出现的问题是由于 session 是默认存储在内存中的,服务器重启之后,session 就丢失了,如果把 session 存储在 Redis 中,那么就能共同访问,并且不丢失数据。
  2. 第二种方案就是引入 token,也就是令牌,用户登录之后,服务器对账号和密码进行验证,验证通过就生成一个令牌,并返回给客户端,客户端收到令牌之后,把令牌存储起来,之后再发起其他请求就带着令牌,处理请求的服务器校验令牌是否有效即可

引入令牌之后就解决了集群环境下的认证问题,并且减轻了服务器的存储压力,令牌由客户端存储,服务器只负责生成和校验

2. JWT 的介绍

官网:JSON Web Tokens - jwt.io

JWT 令牌本身是一个字符串,包括头部,载荷,签名三部分,将信息作为 JSON 对象进行传输

头部:包括令牌的类型和使用的哈希算法

载荷:存储的有效信息,为自定义内容

签名:用于防止 JWT 内容被篡改(并不是防止被解析),只要被篡改,令牌就会失效

3. JWT 的使用

首先需要导入对应的依赖:

<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.11.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-impl -->
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-impl</artifactId><version>0.11.5</version><scope>runtime</scope>
</dependency>
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if Gson is preferred --><version>0.11.5</version><scope>runtime</scope>
</dependency>

接下来就可以测试生成 token 了

//生成token
@Test
public void getToken() {String secret = "abcdefghijklmnopqrstuvwxyz";//设置key,用于签名Key key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(secret));//载荷Map<String, Object> map = new HashMap<>();map.put("name", "zhangsan");map.put("id", 1);//生成tokenString compact = Jwts.builder().setClaims(map).signWith(key).compact();System.out.println(compact);
}

此时报出了一个错误,要求使用提供的方法来生成 key

接下来看怎么生成 key

@Test
public void genKey(){//生成keySecretKey secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256);//转化为String类型String enconde = Encoders.BASE64.encode(secretKey.getEncoded());System.out.println(enconde);
}

生成之后就可以替换掉原来自定义的字符串了,再去生成 token

在官网中也是可以校验成功的

接下来看怎么通过方法来进行 token 的校验:

//校验token
@Test
public void parseToken(){String token = "eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiemhhbmdzYW4iLCJpZCI6MX0.xllreml0yt9aQDXSQe0ngQb45VpV5843rOEKdDQ4QCk";//JWT解析器JwtParser build = Jwts.parserBuilder().setSigningKey(key).build();//对创建好的token进行解析Object body = build.parse(token).getBody();System.out.println(body);
}

如果说签名错了就无法正确解析了:

这就可以通过 try- catch 进行逻辑处理了:

根据这些就可以写一个工具类,服务端就可以直接调用了

@Slf4j
public class JwtUtil {//设置key,用于签名private final static String secret = "WHMgtn1tTrIxc00ys17ukp65bf2KZ0wrihyqynY18F8=sssss";private final static Key key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(secret));private final static long expiration = 24 * 60 * 60 * 1000;//生成tokenpublic static String getToken(Map<String, Object> map) {return Jwts.builder().setClaims(map).setExpiration(new Date(System.currentTimeMillis() + expiration))//设置过期时间.setIssuedAt(new Date())  //设置签发日期.signWith(key).compact();}//校验tokenpublic static Claims parseToken(String token) {if (!StringUtils.hasLength(token)) {return null;}//JWT解析器JwtParser build = Jwts.parserBuilder().setSigningKey(key).build();//对创建好的token进行解析Claims body = null;try {body = build.parseClaimsJws(token).getBody();return body;} catch (SignatureException e) {log.error("token非法...e{}", e.getMessage());} catch (ExpiredJwtException e) {log.error("token过期... e{}", e.getMessage());} catch (Exception e) {log.error("token解析失败,e{}", e.getMessage());}return body;}
}

相关文章:

如何通过 JWT 来解决登录认证问题

1. 问题引入 在登录功能的实现中 传统思路&#xff1a; 登录页面时把用户名和密码提交给服务器服务器验证用户名和密码&#xff0c;并把检验结果返回给后端如果密码正确&#xff0c;则在服务器端创建 session&#xff0c;通过 cookie 把 session id 返回给浏览器 但是正常情…...

高效集成:将聚水潭数据导入MySQL的实战案例

聚水潭数据集成到MySQL&#xff1a;店铺信息查询案例分享 在数据驱动的业务环境中&#xff0c;如何高效、准确地实现跨平台的数据集成是每个企业面临的重要挑战。本文将聚焦于一个具体的系统对接集成案例——将聚水潭的店铺信息查询结果集成到MySQL数据库中&#xff0c;以供BI…...

Jenkins-基于 JNLP协议的 Java Web 启动代理

在上一篇的基础配置上进行以下步骤 工作流程&#xff1a; 通过 JNLP 启动代理&#xff0c;客户端从 Jenkins 服务器上下载一个 agent.jar 文件。该文件启动时&#xff0c;代理程序通过 JNLP 协议连接到 Jenkins 主节点。一旦连接成功&#xff0c;代理节点就可以执行从主节点分…...

Qt数据库操作-QSqlQueryModel 的使用

QSqlQueryModel 功能概述 QSqlQueryModel 是 QSqlTableModel 的父类。QSqlQueryModel 封装了执行 SELECT 语句从数据库查询数据的功能&#xff0c;但是 QSqlQueryModel 只能作为只读数据源使用&#xff0c;不可以编辑数据。QSqlQueryModel 类的主要函数如下&#xff1a; 接口…...

C语言编程1.21波兰国旗问题

题目描述 桌上有 n ( 1 < n < 10000 ) 面小旗&#xff0c;一部分是白旗&#xff0c;一部分是红旗(波兰国旗由白色和红色组成)。唯一允许的操作是交换两面小旗位置。请你设计一个算法&#xff0c;用最少的交换操作将所有的白旗都置于红旗的之前。 输入格式 第一行为一个…...

如何利用微型5G网关为智慧无人矿车提供精确定位

随着5G、AI、物联网技术的发展和普及&#xff0c;越来越多行业正在加快生产、运营、管理的无人化、数字化与智能化&#xff0c;以适应当前我国“智慧、绿色、低碳”的新型发展模式需要。其中矿产业就是典型场景之一。针对矿山场景的智慧化、无人化转型&#xff0c;佰马提供基于…...

使用docker-compese部署SFTPGo详解

官网&#xff1a;SFTP & FTP as a Managed Service (SaaS) and On-premise 一、SFTPGo简介 SFTPGo 是一款功能强大的文件传输服务器软件。它支持多种协议&#xff08;SFTP、SCP、FTP/S、WebDAV、HTTP/S&#xff09;和多个存储后端。 借助 SFTPGo&#xff0c;您可以利用本地…...

Ajax基础总结(思维导图+二维表)

一些话 刚开始学习Ajax的时候&#xff0c;感觉很模糊&#xff0c;但是好像学什么都是这样的&#xff0c;很正常&#xff0c;但是当你学习的时候要持续性敲代码&#xff0c;边敲代码其实就可以理解很多了。然后在最后的总结&#xff0c;其实做二维表之后&#xff0c;就可以区分…...

Spring Task和WebSocket使用

在现代 Web 应用中&#xff0c;WebSocket 作为一种全双工通信协议&#xff0c;为实时数据传输提供了强大的支持。若要确保 WebSocket 在生产环境中的稳定性和性能&#xff0c;使用 Nginx 作为反向代理服务器是一个明智的选择。本篇文章将带你了解如何在 Nginx 中配置 WebSocket…...

微信小程序 本地调试和vconsole可以 但在体验上页面不请求数据

微信小程序页面不请求数据 本地调试和vconsole可以 但在体验版页面不请求数据&#xff0c;如遇到这类问题基本都是一样的解决办法 1、如何调试找到问题 首先要把小程序本地设置的不校验合法域名关掉&#xff0c;不然本地一直都是好的 然后通过本地真机调试打断点找到问题位…...

QT:将QTableWidget内容写入txt文件中

文章详请&#xff1a;最近在做手在眼上的标定&#xff0c;首先要采集机械臂数据和图像数据&#xff0c;我使用tablewidget进行机械臂数据的显示&#xff0c;最后的计算需要将机械臂位姿数据存储在txt文件中。 引用&#xff1a;Qt如何保存tableWidget数据&#xff1f;_qt table…...

前端面试题(六)

1.let,var,const区别 1.作用域&#xff1a;  var&#xff1a;var声明的变量存在函数作用域或全局作用域&#xff0c;这意味着它们在声明它们的函数内部可见&#xff0c;而不在块级作用域内可见。 let和const&#xff1a;let和const声明的变量存在块级作用域&#xff0c;这…...

「Mac畅玩鸿蒙与硬件35」UI互动应用篇12 - 简易日历

本篇将带你实现一个简易日历应用&#xff0c;显示当前月份的日期&#xff0c;并支持选择特定日期的功能。用户可以通过点击日期高亮选中&#xff0c;还可以切换上下月份&#xff0c;体验动态界面的交互效果。 关键词 UI互动应用简易日历动态界面状态管理用户交互 一、功能说明…...

Leetcode581. 最短无序连续子数组(HOT100)

链接 我的代码&#xff1a; class Solution { public:int findUnsortedSubarray(vector<int>& nums) {vector<int> res nums;sort(res.begin(),res.end());int l 0,r nums.size()-1;while(nums[l]res[l]){l;if(lnums.size()){return 0;}}while(nums[r]res…...

HTML前端开发-- Flex布局详解及实战

引言 Flex布局&#xff0c;全称为Flexible Box Layout&#xff0c;是一种现代CSS布局技术&#xff0c;它提供了一种更有效的方式来设计响应式布局和复杂页面布局。本文将详细介绍Flex布局的基本概念、属性以及实战应用。 一、基本概念 Flex布局的核心是Flex容器&#xff08;…...

基于JWT跨语言开发分布式业务系统的挑战与实践:多语言协作的最佳方案

在现代分布式架构下&#xff0c;开发团队往往由来自不同技术栈和开发语言的工程师组成。如何有效地管理这些开发人员的协作&#xff0c;尤其是在实现跨语言的认证与授权机制时&#xff0c;成为了开发者面临的一个重大挑战。JSON Web Token&#xff08;JWT&#xff09;作为一种轻…...

二分法篇——于上下边界的扭转压缩间,窥见正解辉映之光(2)

前言 上篇介绍了二分法的相关原理并结合具体题目进行讲解运用&#xff0c;本篇将加大难度&#xff0c;进一步强化对二分法的掌握。 一. 寻找峰值 1.1 题目链接&#xff1a;https://leetcode.cn/problems/find-peak-element/description/ 1.2 题目分析: 题目要求返回数组内…...

什么是 Kata Containers?

什么是 Kata Containers&#xff1f; Kata Containers 是一种结合了容器技术和虚拟机技术的轻量级运行时&#xff0c;旨在提供容器的速度和虚拟机的安全性。它将容器运行在一个隔离的虚拟机中&#xff0c;从而大幅提升安全性&#xff0c;同时保持容器的高效性。 Kata Contain…...

SpringMvc项目配置RabbitMq

前言&#xff1a;只有消费者部分&#xff0c;没有记录生产者部分 结构图 配置类 可以xml配置&#xff0c;也可以配置类&#xff0c;二者可以相互转化。两种bean注入的方式。 import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; import org.spring…...

shell编程(4)脚本与用户交互以及if条件判断

shell编程&#xff08;4&#xff09;脚本与用户交互以及if条件判断 声明&#xff01; 学习视频来自B站up主 ​泷羽sec​​ 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章 笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

前端高频面试题2:浏览器/计算机网络

本专栏相关链接 前端高频面试题1&#xff1a;HTML/CSS 前端高频面试题2&#xff1a;浏览器/计算机网络 前端高频面试题3&#xff1a;JavaScript 1.什么是强缓存、协商缓存&#xff1f; 强缓存&#xff1a; 当浏览器请求资源时&#xff0c;首先检查本地缓存是否命中。如果命…...

WebRTC调研

WebRTC是什么&#xff0c;为什么&#xff0c;如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...