JWT 单点登录探析:原理、用途与安全实践

JWT 单点登录探析:原理、用途与安全实践

什么是 JWT?

JWT (JSON Web Token) 是目前最流行的跨域认证解决方案,是一种基于 Token 的认证授权机制

从 JWT 的全称可以看出,JWT 本身也是 Token,一种规范化之后的 JSON 结构的 Token。

通过数字签名的方式,以 JSON 对象为载体,在不同的服务终端之间安全的传输信息。

JWT 自身包含了身份验证所需要的所有信息,因此,我们的服务器不需要存储 Session 信息。这显然增加了系统的可用性和伸缩性,大大减轻了服务端的压力。(JWT 存储在【客户端】)

并且,使用 JWT 认证可以有效避免 CSRF 攻击,因为 JWT 一般是存在在 localStorage 中,使用 JWT 进行身份验证的过程中是不会涉及到 Cookie 的。

JWT 有什么用?

JWT 最常见的场景就是授权认证,一旦用户登录,后续每个请求都将包含 JWT,系统在每次处理用户请求的之前,都要先进行 JWT 安全校验,通过之后再进行处理。

JWT 的组成

JWT 由 3 部分组成,用 . 拼接

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJ1c2VybmFtZSI6IlRvbSIsInJvbGUiOiJhZG1pbiIsInN1YiI6ImFkbWluLXRlc3QiLCJleHAiOjE2MjMyMjM2NzUsImp0aSI6ImQ2MTJjZjcxLWI5ZmUtNGMwNy04MzQwLTViOWViZmMyNjExNyJ9
.FOS9Y7rYNdc2AOidnSPrgg2XTYePU0yGZ598h2gtabE

可以在 jwt.io 这个网站上对 JWT 进行解码,解码之后得到的就是 Header、Payload、Signature 这三部分。

这三部分分别是:

Header

Header 通常由两部分组成:

  • typ(Type):令牌类型,也就是 JWT。
  • alg(Algorithm):签名算法,比如 HS256。

JSON 形式的 Header 被转换成 Base64 编码,成为 JWT 的第一部分。

{'typ': 'JWT','alg': 'HS256'
}

Payload 声明

Payload 也是 JSON 格式数据,其中包含了 Claims(声明,包含 JWT 的相关信息)。

Payload 部分默认是不加密的,一定不要将隐私信息存放在 Payload 当中!!!

JSON 形式的 Payload 被转换成 Base64 编码,成为 JWT 的第二部分

Claims 分为三种类型:

  • Registered Claims(注册声明):预定义的一些声明,建议使用,但不是强制性的。
  • Public Claims(公有声明):JWT 签发方可以自定义的声明,但是为了避免冲突,应该在 IANA JSON Web Token Registry 中定义它们。
  • Private Claims(私有声明):JWT 签发方因为项目需要而自定义的声明,更符合实际项目场景使用。

下面是一些常见的注册声明:

  • iss(issuer):JWT 签发方。
  • iat(issued at time):JWT 签发时间。
  • sub(subject):JWT 主题。
  • aud(audience):JWT 接收方。
  • exp(expiration time):JWT 的过期时间。
  • nbf(not before time):JWT 生效时间,早于该定义的时间的 JWT 不能被接受处理。
  • jti(JWT ID):JWT 唯一标识。
{"uid": "ff1212f5-d8d1-4496-bf41-d2dda73de19a","sub": "1234567890","name": "John Doe","exp": 15323232,"iat": 1516239022,"scope": ["admin", "user"]
}
{"sub": '1234567890',"name": 'john',"admin": true
}

Signature 签名

Signature 部分是对前两部分的签名,作用是防止 JWT(主要是 payload)被篡改

这个签名的生成需要用到:

  • Header + Payload。
  • 存放在服务端的密钥(一定不要泄露出去)。 – secret
  • 签名算法。 – HMACSHA256
// 第一种方式
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);
var signature = HMACSHA256(encodedString, 'secret');// 第二种方式
HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)

算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,这个字符串就是 JWT 。

相关依赖

pom.xml 文件

<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version>
</dependency><dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.0</version>
</dependency>
<dependency><groupId>com.sun.xml.bind</groupId><artifactId>jaxb-impl</artifactId><version>2.3.0</version>
</dependency>
<dependency><groupId>com.sun.xml.bind</groupId><artifactId>jaxb-core</artifactId><version>2.3.0</version>
</dependency>
<dependency><groupId>javax.activation</groupId><artifactId>activation</artifactId><version>1.1.1</version>
</dependency>

开源工具类使用

也可用 Hutool 中的工具类生成 JWT 来进行食用:JWT工具-JWTUtil (hutool.cn)

如何基于 JWT 进行身份验证?

在基于 JWT 进行身份验证的的应用程序中,

服务器通过 Payload、Header 和 Secret(密钥)创建 JWT 并将 JWT 发送给客户端。

客户端接收到 JWT 之后,会将其保存在 Cookie 或者 localStorage 里面,以后客户端发出的所有请求都会携带这个令牌。

从用户的角度来分析:

  1. 用户向服务器发送用户名、密码以及验证码用于登陆系统。
  2. 如果用户用户名、密码以及验证码校验正确的话,服务端会返回已经签名的 Token,也就是 JWT。
  3. 用户以后每次向后端发请求都在 Header 中带上这个 JWT 。
  4. 服务端检查 JWT 并从中获取用户相关信息。

为什么用 JWT 代替 Session

JWT (JSON Web Token) 被用于代替传统的基于 Session 的身份认证和授权机制的主要原因有以下几点:

  1. 无需服务器存储: 在传统的 Session 机制中,服务器需要维护每个用户的会话状态,通常是存储在内存或数据库中。而使用 JWT,所有的用户信息和权限信息都被编码到了 token 中,服务器无需存储任何状态信息,这样可以减轻服务器的负担。
  2. 跨域支持: JWT 可以轻松地在多个域之间进行传递和使用,这使得跨域通信和微服务架构变得更加简单。
  3. 扩展性: JWT 是一种开放标准,可以支持自定义的声明和数据结构。这使得 JWT 非常灵活,可以根据实际需求添加额外的信息。
  4. 无状态性: 传统的基于 Session 的认证机制需要服务器保存会话状态,而 JWT 是无状态的。每个请求都包含了认证信息,服务器不需要再去查询数据库或存储中心来验证用户的身份。
  5. 安全性: JWT 内置了签名机制,可以验证 token 的真实性和完整性。这样即使 token 被篡改,服务器也能识别出来并拒绝该 token。
  6. 适用于分布式系统: JWT 适用于分布式系统和微服务架构,可以跨多个服务进行认证和授权。

总的来说,JWT 是一种轻量级、可扩展、无状态和安全的认证机制,相较于传统的基于 Session 的认证机制,JWT 具有更多优势,特别适合于现代的分布式、跨域和无状态的应用场景。

单点登录

两种单点登录实现方案

  1. redis + token
    • token 是指一个无意义的,随机的字符串
    • 后端校验用户名密码之后,生成 token 后放入 redis
    • 前端将 token 放入 header(利用 store
    • 其他页面请求校验时,从 header 获取 token,然后根据 token 到 redis 获取数据进行判断,有数据则登录校验成功。(主要是看 token 是否已失效)
  2. jwt
    • jwt 生成的 token 是有意义的
    • 使用工具包来校验 token

操作细节

1、前端在用户登录之后保存登录信息

          // 变量提交:保存登录信息, 即 tokenstore.commit("setMember", data.content);

2、修改 axios 全局拦截器

为请求 headers 增加 token,并返回配置

axios.interceptors.request.use(function (config) {console.log('请求参数:', config);const _token = store.state.member.token;if (_token) {config.headers.token = _token;console.log("请求headers增加token:", _token);}return config;
}, error => {return Promise.reject(error);
});

JWT 单点登录原理与存在的问题及解决方案

Hutool 对 JWT 的介绍:概述 (hutool.cn)

存在的问题分析:

  1. token 被解密

    • 加盐值(密钥),每个项目的盐值不能一样,避免一个项目被破解,全部项目都被破解
  2. token 被拿到第三方使用

    • 简单来说就是: 自己的产品,被别人包了一个界面,做成他们收费的产品。(比如 ChatGPT 聊天机器人,外表包装成一个小程序,实际上是利用开发者设置的 token 去官网请求信息)

    • 没啥好办法,只能使用限流(检测流量大的情况)

学习参考

  • JWT 基础概念详解
  • 用户认证:基于jwt和session的区别和优缺点

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

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

相关文章

给WordPress网站添加返回顶部按钮

给WordPress网站底部添加一个按钮&#xff0c;点它就可以现实快速返回到顶部。有两种方法可以现实&#xff0c;一种是通过安装相关插件来实现。另外一种方式就是以纯属代码的方式来实现。 给WordPress网站底部添加一个按钮&#xff0c;点它就可以现实快速返回到顶部。有两种方…

操作系统 面试第一弹

1. 进程和线程的区别 进程&#xff08;Process&#xff09;和线程&#xff08;Thread&#xff09;是操作系统中的重要概念&#xff0c;它们表示执行中的程序的不同执行单元。下面是它们的区别&#xff1a; 定义&#xff1a;进程是一个独立的执行环境&#xff0c;具有独立的内存…

【深度学习】DataComp论文,数据集介绍,大数据模型的数据集介绍

参考&#xff1a; https://laion.ai/blog/datacomp/ 论文&#xff1a;https://arxiv.org/abs/2304.14108 文章目录 论文报告的一些内容datacomp-1B 数据质量比lainon2B要好不同规模数据有多少数据数据处理数据来源 论文报告的一些内容 摘要 多模态数据集是近期如CLIP、Stable …

TCP服务器的演变过程:IO多路复用机制select实现TCP服务器

IO多路复用机制select实现TCP服务器 一、前言二、新增使用API函数2.1、select()函数2.2、FD_*系列函数 三、实现步骤四、完整代码五、TCP客户端5.1、自己实现一个TCP客户端5.2、Windows下可以使用NetAssist的网络助手工具 小结 一、前言 手把手教你从0开始编写TCP服务器程序&a…

洛谷——【数据结构1-2】二叉树

文章目录 题目【深基16.例1】淘汰赛题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1基本思路&#xff1a;代码 【深基16.例3】二叉树深度题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1基本思路&#xff1a;代码 [USACO3.4] 美国血统 American Heritage题目描…

算符优先语法分析设计原理与实现

前言&#xff1a; 作者的词法分析程序以及算符优先语法分析设计程序仓库链接 1、目标任务 **[实验项目] **以专题 1 词法分析程序的输出为语法分析的输入&#xff0c;实现算符优先分析算法&#xff0c;完成以下描述算术表达式的算符优先文法的算符优先分析过程。 G[E]:E→E…

Spark编程实验三:Spark SQL编程

目录 一、目的与要求 二、实验内容 三、实验步骤 1、Spark SQL基本操作 2、编程实现将RDD转换为DataFrame 3、编程实现利用DataFrame读写MySQL的数据 四、结果分析与实验体会 一、目的与要求 1、通过实验掌握Spark SQL的基本编程方法&#xff1b; 2、熟悉RDD到DataFram…

代码随想录算法训练营第二十七天 | 回溯算法part4

力扣题目 用时&#xff1a;未知 1、93.复原IP地址 2、78.子集 3、90.子集II 力扣题目记录 93.复原IP地址 这个题和上一个题差不多&#xff0c;只是4段数字&#xff0c;只有三个句点&#xff0c;所以第四段要单独处理判断子串是否合法 class Solution { private:vector<s…

Qt/QML编程学习之心得:实现一个图片浏览器(十八)

QML中有个重要控件,经常使用就是image,通常可以用它来显示一张图片。如果想结合openfiledialog来让image显示图片,也就是做一个简易的图片浏览器,怎么弄呢? DefaultFileDialog.qml: import QtQuick 2.0 import QtQuick.Dialogs 1.0FileDialog {id: fileDialogtitle: &qu…

2024免费的数据恢复软件EasyRecovery14自己操作就能恢复的方法

而今天小编为大家还是带来了同系列软件easyrecovery14&#xff0c;这是easyrecovery数据恢复软件中的技术员版本&#xff0c;不仅包含家庭版和专业版的所有功能&#xff0c;而且还旨在简化技术人员的数据恢复过程。软件拥有强大的数据恢复功能&#xff0c;支持使用的恢复场景有…

KNN与KD树博客总结

目录 总结小结&#xff1a; 总结 原始篇&#xff1a;KNN算法及其优缺点算法思想改进篇&#xff1a;KD树&#xff08;KNN的plus版算法实现第一篇&#xff1a;平衡二叉树的构建&#xff08;递归算法实现第二篇&#xff1a;KD树的构建&#xff08;递归算法实现第三篇&#xff1a;…

CentOS 7 设置网络

CentOS 7 设置网络 正常情况 ①登陆进去之后使用下面的命令修改文件 echo ONBOOTyes >> /etc/sysconfig/network-scripts/ifcfg-ens33②如果是虚拟机重启后使用如下命令进行查看IP地址 ip addr注&#xff1a;到这里如果显示有两部分&#xff0c;则代表网络设置成功&a…

华为设备VRP系统管理

为了满足企业业务对网络的需求&#xff0c;网络设备中的系统文件需要不断进行升级。另外&#xff0c;网络设备中的配置文件也需要时常进行备份&#xff0c;以防设备故障或其他灾害给业务带来损害。在升级和备份系统文件或配置文件时&#xff0c;经常会使用FTP和TFTP来传输文件。…

服务器系统时间不同步如何处理

在分布式计算环境中&#xff0c;服务器系统时间的同步至关重要。然而&#xff0c;由于各种原因&#xff0c;服务器系统时间不同步的问题时有发生,这可能会导致严重的问题&#xff0c;如日志不准确、证书验证失败等。下面我们可以一起探讨下造成服务器系统时间不同的原因以及解决…

【Vue2+3入门到实战】(5)Vue基础之Computed计算属性 详细示例

目录 一、今日学习目标1.computed计算属性 二、computed计算属性1.概念2.语法3.注意4.案例5.代码准备 三、computed计算属性 VS methods方法1.computed计算属性2.methods计算属性3.计算属性的优势4.总结 四、计算属性的完整写法五、综合案例-成绩案例六、Computed计算属性总结 …

【测试开发】测试分类相关知识

文章目录 目录 文章目录 前言 一、测试分类 1.按照测试对象划分&#xff1a; 界面测试&#xff1a; 可靠性测试&#xff1a; 容错性测试&#xff1a; 文档测试 &#xff1a; 兼容性测试 &#xff1a; 易用性测试 &#xff1a; 安装卸载测试 &#xff1a; 安全测试 &#xff1a;…

揭秘Pod状态与生命周期管理的秘密(中)

上一篇文章中主要介绍了Pod的基础概念与使用、删除。本文将带你一起学习Pod的几种容器(Init、Pause) 点击 这里 可以查看所有相关文章。 Init 容器 本文讲解 Init 容器的基本概念&#xff0c;这是一种专用的容器&#xff0c;在应用程序容器启动之前运行&#xff0c;用来包含…

Spring Boot 3.2 新特性之 HTTP Interface

SpringBoot 3.2引入了新的 HTTP interface 用于http接口调用&#xff0c;采用了类似 openfeign 的风格。 具体的代码参照 示例项目 https://github.com/qihaiyan/springcamp/tree/master/spring-http-interface 一、概述 HTTP Interface 是一个类似于 openfeign 的同步接口调…

住宅代理妙用:网络抓取的必备工具

什么是住宅代理&#xff1f; 要准确理解什么是住宅代理&#xff0c;首先需要了解什么是住宅IP。IP 地址是连接到网络时分配给单个设备的唯一标识符。这允许设备或端点直接相互通信&#xff0c;而无需跨线。 住宅IP是指分配给特定设备&#xff08;例如计算机、手机、平板电脑等…

新版IDEA中Git的使用(二)

说明&#xff1a;前面介绍了在新版IDEA中Git的基本操作&#xff0c;本文介绍关于分支合并、拉取等操作&#xff1b; 例如&#xff0c;现在有一个项目&#xff0c;分支如下&#xff1a; main&#xff1a;主分支&#xff1b; dev&#xff1a;开发分支&#xff1b; test&#x…