JWT简单介绍

本文介绍了JWT(JSON Web Tokens)的基本概念、工作原理及其在HTTP无状态协议下的作用。内容涵盖JWT的构成、生成与验证流程,以及JWT在一次性验证、RESTful API无状态认证等场景的应用。同时,讨论了JWT的存储位置、验证方式,以及安全性考虑,如JWT的泄露风险和续签问题。最后,提到了JWT不适合用于单点登录和会话管理的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大家好,我是IT修真院,一枚正直纯洁善良的如刚入门的Java程序员,今天跟大家分享一下修真院官网JAVA任务五,深度思考中的知识点————JWT


1.知识背景

由于HTTP协议是无状态的协议,因此用户登陆后保持登陆状态就是一个需要解决的问题。

  
常规的解决方案有session、cookie、token等方式。

JWT就是一种Token的解决方案。


2.知识剖析

JWT(JSON Web Tokens)是一项RFC的标准,由RFC 7519定义,用于两个实体之间安全地传输用JSON表示的数据。在传输过程中,JWT表现为一个字符串,可以通过HTTP的参数或者Header传输,由三部分字符串用点号相连,格式如下:

header.payload.signature

①首先用户通过用户名密码向认证服务器发起请求

②认证服务器核实用户身份之后,生成一个Token返回到客户端,这个生成过程如下:首先构造称为header的JSON对象:

{
“typ”:”JWT”,
“alg”:”HS256”
}

这个JSON包含两个字段,typ表示Token的类型,一般情况下为JWT,alg表示签名算法,这里我们使用HMACSHA256算法。

接着是payload部分,认证服务器验证密码后找到用户的ID,将其放入payload,并且给定一个过期时间:

{
“userId”:”b08f86af-35da-48f2-8fab-cef3904660bd”,
“exp”:1371720939
}

接着我们把header和payload分别使用base64urlEncode算法编码,然后用点号连接起来,并且使用私钥和HS256算法进行签名。

通过以上的过程,认证服务器将jwt返回的客户端,格式如:

aaaaaaaaaaaaaa.bbbbbbbbbbbbbbbbb.cccccccccccccccc

需要注意的是,JWT并没有加密,而只是进行编码和签名,没有解决安全性问题,https等基础设施依然必要。

③OK,客户端现在拿到JWT,可以使用认证服务器的公钥进行验证,拿到payload里面的数据,用于页面展示等。然后携带JWT想应用服务器请求API。

④API服务器拿到JWT后,同样使用认证服务器的公钥验证签名,判断用户是否经过认证,token是否还在有效期内等,同样可以拿到payload中的用户id,用于日志等数据存储。认证完成之后,将业务数据返回给客户端。


3. 常见问题

JWT放在那里?

JWT如何生成?

JWT如何验证?


4. 解决方案

1.html5存储:localStorage or sessionStorage (Web Storage)

2.放置cookies中

两种方式比较:
相同点:都是无状态的,因为api所需要的验证信息都在token中
不同点:
1.前者可使用跨站点脚本(XSS)进行攻击,cross-site scripting (XSS) attacks。所以,Web存储在传输过程中不执行任何安全标准。
2.Cookie与HttpOnly cookie标志一起使用时,不能通过JavaScript访问,并且不受XSS影响。但是传统的cookies不符合RESTful最佳实践,因为需要服务器存储。cookies+JWT不需要将状态存储在服务器上。这是因为JWT封装了服务器为请求提供服务所需的所有内容。

JWT放在那里?

结论:建议存储在cookie中

JWT如何验证?

JWT对多种语言都有支持,java中有不少第三方的制品库。

我在项目中使用的是Auth0的JWT包。

JWT如何验证?

编写拦截器,首先验证合法性(是否可以被正确解析),是否过期(exp时间戳对比当前时间),再对其中的几个重要字段进行检查。


5. 编码实战

见视频


6.扩展思考

什么场景该适合使用jwt?

1、一次性验证:比如用户注册后需要发一封邮件让其激活账户,通常邮件中需要有一个链接,这个链接需要具备以下的特性:能够标识用户,该链接具有时效性(通常只允许几小时之内激活),不能被篡改以激活其他可能的账户…这种场景就和 jwt 的特性非常贴近,jwt 的 payload 中固定的参数:iss 签发者和 exp 过期时间正是为其做准备的。

2、restful api的无状态认证: 使用 jwt 来做 restful api 的身份认证也是值得推崇的一种使用方案。客户端和服务端共享 secret;过期时间由服务端校验,客户端定时刷新;签名信息不可被修改…spring security oauth jwt 提供了一套完整的 jwt 认证体系,以笔者的经验来看:使用 oauth2 或 jwt 来做 restful api 的认证都没有大问题,oauth2 功能更多,支持的场景更丰富,后者实现简单。

但是不推荐用JWT做单点登陆和会话管理

首先 cookie+jwt 的方案前提是非跨域的单点登录(cookie 无法被自动携带至其他域名),其次单点登录系统包含了很多技术细节,至少包含了身份认证和会话管理,这还不涉及到权限管理。如果觉得比较抽象,不妨用传统的 session+cookie 单点登录方案来做类比,通常我们可以选择 spring security(身份认证和权限管理的安全框架)和 spring session(session 共享)来构建,而选择用 jwt 设计单点登录系统需要解决很多传统方案中同样存在和本不存在的问题。

jwt token泄露了怎么办?

遵循如下的实践可以尽可能保护你的 jwt 不被泄露:使用 https 加密你的应用,返回 jwt 给客户端时设置 httpOnly=true 并且使用 cookie 而不是 LocalStorage 存储 jwt,这样可以防止 XSS 攻击和 CSRF 攻击

续签问题

传统的 cookie 续签方案一般都是框架自带的,session 有效期 30 分钟,30 分钟内如果有访问,session 有效期被刷新至 30 分钟。而 jwt 本身的 payload 之中也有一个 exp 过期时间参数,来代表一个 jwt 的时效性,而 jwt 想延期这个 exp 就有点身不由己了,因为 payload 是参与签名的,一旦过期时间被修改,整个 jwt 串就变了,jwt 的特性天然不支持续签。

如果一定要使用 jwt 做会话管理(payload 中存储会话信息),也不是没有解决方案

解决方案:

每次请求刷新 jwt

只要快要过期的时候刷新 jwt

完善 refreshToken

使用 redis 记录独立的过期时间


7. 参考文献

http://blog.didispace.com/learn-how-to-use-jwt-xjf/

http://www.jdon.com/artichect/json-web-tokens.html

https://blog.youkuaiyun.com/HaixWang/article/details/79661209


今天的分享就到这里啦,欢迎大家点赞、转发、留言、拍砖~

PPT

视频


技能树.IT修真院

“我们相信人人都可以成为一个工程师,现在开始,找个师兄,带你入门,掌控自己学习的节奏,学习的路上不再迷茫”。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值