一步步教你实现JWT认证和授权
一步步教你实现JWT认证和授权
- 前言
 - 一、引入
 - 二、Token认证与JWT认证的关系
 - 三、什么是JWT认证?
 - 四、JWT的组成
 - 1、头部(Header)
 - 2、载荷(Payload)
 - 3、签名(Signature)
 
- 五、JWT认证的工作流程
 - 六、代码举例
 - 七、总结
 
前言
本博主将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识,有兴趣的小伙伴可以关注博主!
 也许一个人独行,可以走的很快,但是一群人结伴而行,才能走的更远!
 
一、引入
我们上篇文章中为大家介绍了token(令牌)认证的认证机制,而在本文,我们要为大家介绍JWT认证(JSON Web Token authentication)。
二、Token认证与JWT认证的关系
大家现在是否感觉压力山大,不仅学习了Cookie认证,Session认证,还学习了一个Token认证,现在又冒出来了个JWT认证,别担心,这个JWT认证并不是什么新颖的认证方式,本质上它就是一种基于Token的身份验证机制,Token认证是一种通用的身份验证方法,我们可以使用不同类型的Token去进行身份验证,而JWT就是其中的一种Token类型。
在这里我们要区分好,上篇文章为大家介绍的Token认证机制是一个广泛的概念,是一种概称,它涵盖了使用不同类型的Token进行身份验证的方法。除了JWT之外,还有其他类型的Token,例如基于时间的令牌(Time-based Tokens)和访问令牌(Access Tokens)。这些Token可以使用不同的格式和验证机制,但它们都是用于验证用户身份并授权访问受保护资源的凭据。
所以搞清了关系之后,接下来进入正文!
三、什么是JWT认证?
JWT认证(JSON Web Token authentication)是一种基于Token的身份验证机制。它使用JSON Web Token(JWT)作为身份验证的凭据,并通过对JWT进行验证来确认用户的身份和授权用户访问受保护的资源。
四、JWT的组成
上文已经提及,JWT只是众多token类型里的其中一种类型,所以关于它的组成,就是我们要学习的重点。
JWT是一种开放标准(RFC 7519),定义了一种紧凑且自包含的方式来表示和传输信息。它由三个部分组成:
- 头部(Header):包含描述JWT的元数据和算法信息,例如使用的签名算法。
 - 载荷(Payload):包含JWT所声明的数据,可以包含用户身份信息、授权信息和其他自定义数据。
 - 签名(Signature):使用密钥和指定的签名算法对头部和载荷进行签名,以实现数据完整性和验证。
 

1、头部(Header)
头部通常包含两个部分:令牌类型(typ)和签名算法(alg)。这些信息用于描述JWT的类型和使用的加密算法。例如,一个典型的头部可以是以下JSON格式:
{"alg": "HS256","typ": "JWT"
}
 在上面的例子中,"alg"表示签名算法为HMAC SHA-256(HS256),"typ"表示令牌类型为JWT。
2、载荷(Payload)
载荷是JWT的主体部分,包含要传输的数据。载荷可以包含一些预定义的声明(Claims),也可以包含自定义的声明。预定义的声明分为三类:
- 注册声明(Registered Claims):这些声明是一组预定义的标准声明,包括iss(签发者)、sub(主题)、aud(受众)、exp(过期时间)、nbf(生效时间)和iat(发布时间)等。
 - 公共声明(Public Claims):这些声明是自定义的声明,供使用者自由定义,但建议遵循一定的命名规范,避免冲突。
私有声明(Private Claims):这些声明也是自定义的声明,但为了避免冲突,建议将其命名为命名空间形式,例如"company_name"。
以下是一个示例载荷的JSON格式: 
{"sub": "user123","name": "John Doe","iat": 1629012345
}
 在上面的例子中,"sub"表示主题为"user123"的用户,“name"表示用户姓名为"John Doe”,"iat"表示JWT的发布时间为1629012345(UNIX时间戳)。
3、签名(Signature)
签名是JWT的第三部分,用于验证JWT的完整性和真实性。签名通常使用头部和载荷中的数据以及一个密钥来生成。生成签名的过程是对头部和载荷进行编码,然后使用指定的签名算法(如HMAC、RSA等)进行加密。最终生成的签名字符串将附加在JWT的末尾。
签名的示例:
HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload),secretKey
)
 在上面的例子中,"header"表示头部的Base64编码字符串,"payload"表示载荷的Base64编码字符串,"secretKey"表示用于生成签名的密钥。
通过将这三个部分使用句点(.)连接起来,即可形成一个完整的JWT:
base64UrlEncode(header) + "." +
base64UrlEncode(payload) + "." +
signature
 最终的JWT可以作为身份验证凭据在客户端和服务器之间进行传输,并通过验证签名来验证JWT的真实性和完整性。
当然很多人会疑惑这个token的安全性,JWT是由三部分组成的,以点分开header、payload和signature
-  
header部分声明需要用什么算法来生成签名
 -  
payload部分是一些特定的数据,比如有效期之类
 -  
接着header和payload两部分的内容会经由BASE64编码,注意是编码,不是加密,也就是很容易可以解码,虽然JWT不保存在服务器这里,但是服务器需要保存一段密码,这段密码要结合两段编码进行算法运算,最终得到签名信息。这里使用的算法就是刚刚header声明的算法。签名的信息,也就是signature部分了,这样一个完整的最大的JWT就可以发送给客户端了。如果我们修改三个部分,其中一个字符,整个最大JWT都会出错,三个部分是相关联的,因此JWT有一定的安全性。
 

 token是服务器加密的用户信息,服务器将token发给浏览器,浏览器用cookie或storage保存cookie。然后浏览器每次发送请求就带上token,服务器将其解密并确认用户登录。
五、JWT认证的工作流程
JWT认证的工作流程一般涉及以下步骤:
-  
用户身份验证:
用户在进行身份验证时,通常会提供标识自己身份的凭据(例如用户名和密码)。服务器需要验证这些凭据的有效性,通常是通过与存储在数据库中的用户凭据进行比对。 -  
JWT的生成:
如果用户通过身份验证,服务器将生成一个JWT作为身份验证的凭据。生成JWT的过程包括以下步骤:- 创建一个包含头部和载荷的JSON对象。
 - 对头部和载荷进行Base64编码,生成JWT的第一部分。
 - 使用服务器上的密钥和指定的签名算法对编码后的头部和载荷进行签名,生成签名。
 - 将签名与编码后的头部和载荷连接起来,生成完整的JWT。
 
 -  
JWT的发送和存储:
服务器将生成的JWT发送给客户端,通常是通过将JWT作为响应的一部分(例如在HTTP响应的头部或作为响应的一部分)返回给客户端。客户端通常会将JWT存储在本地,例如在浏览器的本地存储或内存中。 -  
后续请求的身份验证:
在后续的请求中,客户端将JWT作为身份验证凭据发送给服务器。通常是通过将JWT放置在请求的头部(例如Authorization头部)中或作为请求参数的一部分(例如查询字符串或表单数据)发送给服务器。 -  
JWT的验证和解析:
服务器在接收到请求后,需要验证JWT的有效性和完整性,以及解析其中的信息。验证和解析的过程包括以下步骤:- 从请求中获取JWT。
 - 检查JWT的签名是否有效,以确保JWT未被篡改。
 - 解码JWT的头部和载荷,获取其中的信息。
 
 -  
用户授权和访问受保护资源:
服务器通过验证JWT的有效性,并获取到其中的用户身份信息,确认用户的身份。基于用户的身份信息,服务器可以进行授权判断,决定用户是否有权访问请求的资源。如果用户被授权访问资源,服务器将返回相应的数据或执行相应的操作。 
整个JWT认证的工作流程是基于无状态的,服务器无需在后端存储会话状态,每个请求都是独立的。JWT作为身份验证凭据,提供了一种简单、安全和可扩展的方式来验证用户身份,并授权用户访问受保护的资源。

六、代码举例
以下是一个使用Java JWT库(jjwt)的示例代码:
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;import java.util.Date;public class JWTExample {private static final String SECRET_KEY = "yourSecretKey";private static final long EXPIRATION_TIME = 86400000; // 24小时public static void main(String[] args) {// 创建JWTString token = createJWT("user123");// 验证和解析JWTif (validateJWT(token)) {String username = parseJWT(token);System.out.println("解析到的用户名:" + username);} else {System.out.println("JWT验证失败");}}public static String createJWT(String username) {Date now = new Date();Date expiration = new Date(now.getTime() + EXPIRATION_TIME);String token = Jwts.builder().setSubject(username).setIssuedAt(now).setExpiration(expiration).signWith(SignatureAlgorithm.HS256, SECRET_KEY).compact();return token;}public static boolean validateJWT(String token) {try {Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);return true;} catch (Exception e) {return false;}}public static String parseJWT(String token) {Jws<Claims> claims = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);return claims.getBody().getSubject();}
}
 在上述示例中,createJWT方法用于创建JWT,其中设置了用户名、签发时间、过期时间,并使用HS256算法进行签名。validateJWT方法用于验证JWT的合法性,通过解析和校验JWT的签名来进行判断。parseJWT方法用于解析JWT并提取其中的用户名信息。
请注意,上述代码中的SECRET_KEY是用于签名和验证JWT的密钥,请确保将其替换为实际的密钥,并妥善保管。另外,示例中设置的过期时间为24小时(86400000毫秒),我们可以根据自己的需求进行调整。
使用这个示例代码,可以创建一个包含用户名信息的JWT,并验证和解析JWT以获取其中的用户名。
七、总结
大家不要把三者想的太复杂
- session是诞生并保存在服务器那边的,由服务器主导一切。
 - cookie这是一种数据载体,把session放在cookie中送到客户端那边,cookie跟随HTTP的每个请求发送出去。
 - token是诞生在服务器,但保存在浏览器这边的,由客户端主导一切,可以放在cookie或者storage里面,持有token,就像持有令牌一样,可以允许访问服务器。
 - 服务器验证是前提。cookie保存在客户端,服务器不加密不保存;session保存在客户端,服务器要加密并保存;token保存在客户端,服务器要加密不保存。
 - Session是一种服务器端的机制,用于存储和管理用户的身份和状态信息,而Cookie是用于在客户端存储Session ID等数据的机制。Token是一种轻量级的身份验证和授权机制,可以作为无状态的凭据进行传输。Cookie和Token都可以用于在客户端和服务器之间传递身份信息和状态信息,实现身份验证和状态管理的功能。
 
相关文章:
一步步教你实现JWT认证和授权
一步步教你实现JWT认证和授权 前言一、引入二、Token认证与JWT认证的关系三、什么是JWT认证?四、JWT的组成1、头部(Header)2、载荷(Payload)3、签名(Signature) 五、JWT认证的工作流程六、代码举…...
【python 深度学习】解决遇到的问题
目录 一、RuntimeError: module compiled against API version 0xc but this version of numpy is 0xb 二、AttributeError: module ‘tensorflow’ has no attribute ‘flags’ 三、conda 更新 Please update conda by running 四、to search for alternate channels that…...
maxwell 基于zookeeper的高可用方案
Maxwell版本1.39.2 一: 添加zk的pox文件 <!-- customize HA --> <dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>5.4.0</version> </dependency>&…...
【JavaScript】match用法 | 正则匹配
match正则匹配 var e "www.apple.com:baidu.com" var match e.match(/com/g) console.log("match: "match);> "match: com,com"match返回值问题 match的返回值是一个数组 数组的第0个元素是与整个正则表达式匹配的结果 数组的第1个元素是…...
前端css + js +vue +element-ui 实现响应式布局,根据浏览器窗体大小自动响应
前端css js vue element-ui 实现响应式布局,根据浏览器窗体大小自动响应 1、环境2、js代码3、代码解释1、定义对象2、定义方法3、监听窗口变化,计算比例值,并赋值给transform 属性4、实现监听 3、html 代码4、特别注意 1、环境 我的环境是e…...
小程序生成App:轻量低门槛的开发方式
小程序生成App可以成为一种轻量低门槛的开发App的方式,但是需要根据具体情况进行选择。如果应用需要处理大量数据或需要进行复杂计算,或者需要实现原生特有的功能或交互效果,可能需要选择其他开发方式。 在文章开始之前,我们看看目…...
Linux命名管道进程通信
文章目录 前言一、什么是命名管道通信二、创建方式三、代码示例四、文件进程通信总结 前言 命名管道 是实现进程间通信的强大工具,它提供了一种简单而有效的方式,允许不同进程之间进行可靠的数据交换。不仅可以在同一主机上的不相关进程间进行通信&…...
如何将苹果彻底删除视频找回?试试这3种方法
如今是短视频时代,大家通常会使用苹果手机来拍摄视频,以此记录生活中的美好日常。但是大家都知道视频是十分占空间的,这也经常会出现iPhone内存不足,磁盘崩溃的问题。 当遇到iPhone内存不足的情况时,大家往往会选择清…...
【音视频、chatGpt】h5页面最小化后,再激活后视频停住问题的解决
目录 现象 观察 解决 现象 页面有时候要切换,要最小化;短时间或者几个小时内切换回来,视频可以正常续上;而放置较长时间,几个小时或者一晚上,切换回来后,视频可能卡死 观察 切换页面&#x…...
[CSS] 图片九宫格
效果 index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"/><meta http-equiv"X-UA-Compatible" content"IEedge"/><meta name"viewport" content"widthdevice-…...
MChat-Gpt V1.0.0 (将ChatGpt机器人接入内网供全体使用)
Github>https://github.com/MartinxMax/MChat-Gpt 首页 MChat-Gpt V1.0.0将ChatGpt机器人接入内网供全体使用 你需要一个ChatGpt账户如果您在中国则需要使用代理访问,设置TUN代理模式 安装依赖 选择你的系统进行安装 服务端配置 #python3 ChatGpt_Server.py -h 使用&a…...
日常开发中Git命令指北
Git基本操作 创建化仓库 mkdir 目录 cd 目录 git init配置本地仓库 # 配置用户名,邮箱 git config user.name "cxf" git config user.email "1969612859qq.com" # 查看本地配置(小写的 L) git config -l # 重置配置&a…...
API 测试 | 了解 API 接口概念|电商平台 API 接口测试指南
什么是 API? API 是一个缩写,它代表了一个 pplication P AGC 软件覆盖整个房间。API 是用于构建软件应用程序的一组例程,协议和工具。API 指定一个软件程序应如何与其他软件程序进行交互。 例行程序:执行特定任务的程序。例程也称…...
【计算机组成原理】24王道考研笔记——第三章 存储系统
第三章 存储系统 一、存储系统概述 现代计算机的结构: 1.存储器的层次结构 2.存储器的分类 按层次: 按介质: 按存储方式: 按信息的可更改性: 按信息的可保存性: 3.存储器的性能指标 二、主存储器 1.基本…...
学习C语言的好处:
基础编程语言:C语言是其他编程语言的基础,学习C语言可为后续学习打下坚实基础,广泛应用于嵌入式系统、操作系统、网络协议等。 简单易学:C语言语法简单易懂,适合初学者。只需文本编辑器和编译器,即可开始编…...
基于k8s的devOps自动化运维平台架构设计(中英文版本)
▲ 点击上方"DevOps和k8s全栈技术"关注公众号 In the rapidly evolving landscape of software development and IT operations, DevOps has emerged as a transformative approach to bridge the gap between development and operations teams. One of the key ena…...
P450进阶款无人机室内定位功能研测
在以往的Prometheus 450(P450)无人机上,我们搭载的是Intel Realsense T265定位模块,使用USB连接方式挂载到机载计算机allspark上,通过机载上SDK驱动T265运行并输出SLAM信息,以此来实现室内定位功能。 为进…...
深度学习,计算机视觉任务
目录 计算机视觉任务 1.K近邻算法 2.得分函数 3.损失函数的作用 4.向前传播整体流程 5.反向传播计算方法 计算机视觉任务 机器学习的流程: 数据获取 特征工程 建立模型 评估与应用 计算机视觉: 图像表示:计算机眼中的图像&#…...
使用 Docker 部署 canal 服务实现MySQL和ES实时同步
文章目录 0. 环境介绍0. 前置步骤1. 安装Kibana和Elasticsearch2. 安装Canal和Canal Adapter2.1 修改数据库配置2.1.1 修改配置2.1.2 验证mysql binlog配置2.1.3 查看日志文件2.1.4 用JDBC代码插入数据库 2.2 安装Canal Server2.3 安装Canal Adapter修改两处配置文件配置文件取…...
const易错详解
const对比 常量指针 int b; (1)const int *a &b;//常量指针(2)int const *a &b; //常量指针常量指针:指向的变量值不能被修改  支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
无人机侦测与反制技术的进展与应用
国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...
Linux中《基础IO》详细介绍
目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改,实现简单cat命令 输出信息到显示器,你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...
面试高频问题
文章目录 🚀 消息队列核心技术揭秘:从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"?性能背后的秘密1.1 顺序写入与零拷贝:性能的双引擎1.2 分区并行:数据的"八车道高速公路"1.3 页缓存与批量处理…...
02.运算符
目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&:逻辑与 ||:逻辑或 !:逻辑非 短路求值 位运算符 按位与&: 按位或 | 按位取反~ …...
【实施指南】Android客户端HTTPS双向认证实施指南
🔐 一、所需准备材料 证书文件(6类核心文件) 类型 格式 作用 Android端要求 CA根证书 .crt/.pem 验证服务器/客户端证书合法性 需预置到Android信任库 服务器证书 .crt 服务器身份证明 客户端需持有以验证服务器 客户端证书 .crt 客户端身份…...
聚六亚甲基单胍盐酸盐市场深度解析:现状、挑战与机遇
根据 QYResearch 发布的市场报告显示,全球市场规模预计在 2031 年达到 9848 万美元,2025 - 2031 年期间年复合增长率(CAGR)为 3.7%。在竞争格局上,市场集中度较高,2024 年全球前十强厂商占据约 74.0% 的市场…...
