浅析JWT

Cookie-session

我们都知道JWT一般用于用户登录等需要记住的操作,在谈论JWT之前就不得不谈谈以前的cookie-session登录了 。因为http协议是一种无状态协议,即每次服务端接收到客户端的请求时,都是一个全新的请求,服务器并不知道客户端的历史请求记录(也就是说你登陆过后哪怕你刷新一下他也不认识你了,还要你继续登录);Session 和 Cookie 的主要目的就是为了弥补 HTTP 的无状态特性。

互联网服务离不开用户认证,一般流程如下:

浅析JWT_第1张图片

 这就是Cookie-session方法 

Session是什么


客户端请求服务端,服务端会为这次请求开辟一块内存空间,这个对象便是 Session 对象,存储结构为 ConcurrentHashMap。Session 弥补了 HTTP 无状态特性,服务器可以利用 Session 存储客户端在同一个会话期间的一些操作记录,如上图所示,我们在这个过程中会存储session_id。

cookie-session机制的缺点

扩展性(scaling)不好


单机当然没有问题,如果是服务器集群,或者是跨域的服务导向架构,就要求 session 数据共享,每台服务器都能够读取 session。比如 A 服务器存储了 Session,在做了负载均衡后,假如一段时间内 A 的访问量激增,会转发到 B 进行访问,但是 B 服务器并没有存储 A 的 Session,会导致 Session 的失效。一种解决方案是 session 数据持久化,写入数据库或别的持久层。各种服务收到请求后,都向持久层请求数据。这种方案的优点是架构清晰,缺点是工程量比较大(session存储在服务端,这就增大了服务器的开销,当用户多的情况下,服务器性能会大大降低)。另外,持久层万一挂了,就会单点失败。

另一种方案是服务器索性不保存 session 数据了,所有数据都保存在客户端(一种非常重要的思想,让客户端帮我们存储或者做计算减少服务端的压力),每次请求都发回服务器。JWT 就是这种方案的一个代表。

安全性差:

Cookie安全性是一个大问题,因为它们是以明文形式存储,可能会造成安全风险,因为任何人都可以打开并篡改cookie。Cookie容易在客户端被发现意味着它们很容易被黑客入侵和修改。也就等于合法登陆了你的账户

浅析JWT_第2张图片 能直接看到cookie

 

JWT

JWT 的原理

服务器认证以后,生成一个 JSON 对象,发回给用户,就像下面这样。

浅析JWT_第3张图片

以后,用户与服务端通信的时候,都要发回这个 JSON 对象。服务器完全只靠这个对象认定用户身份。为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名 。服务器就不保存任何 session 数据了,也就是说,服务器变成无状态了,从而比较容易实现扩展。

JWT的数据结构

实际的JWT就像这样

浅析JWT_第4张图片

我们可以通过JSON Web Tokens - jwt.io 来解析JWT

浅析JWT_第5张图片

它是一个很长的字符串,中间用点(.)分隔成三个部分。注意,JWT 内部是没有换行的,这里只是为了便于展示,将它写成了几行。

JWT 的三个部分依次如下。

浅析JWT_第6张图片

写成一行,就是下面的样子。

浅析JWT_第7张图片

 Header部分是一个JSON对象,描述JWT的元数据

payload部分也是一个json对象,用来存放实际需要传递的数据。JWT 规定了7个官方字段,供选用。

浅析JWT_第8张图片

 除了官方字段,你还可以在这个部分定义私有字段,下面就是一个例子。

浅析JWT_第9张图片

注意,JWT 默认是不加密的,任何人都可以读到,所以不要把秘密信息放在这个部分。

Signature 部分是对前两部分的签名,防止数据篡改。

JWT的使用方式

客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage。

此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息Authorization字段里面。

 另一种做法是,跨域的时候,JWT 就放在 POST 请求的数据体里面。

JWT的特点

浅析JWT_第10张图片

说完JWT,你可能还是会有疑惑,这不和cookie-session差不多吗?cookie-session返回session_id,JWT返回token,那你cookie可能会被截获并修改那你token就不会了吗?

事实上,JWT可以通过Signature字段来防止token被篡改。使用私钥加密生成token  公钥解密获取token中的信息

另一方面采用https 或者 代码层面也可以做安全检测,比如ip地址发生变化,MAC地址发生变化等等,可以要求重新登录

由于token生成后无法设置该token为无效,所以只能采用设置token过期时间来生成新的refresh_token。以及应该使用HTTPS协议传输(这些都是上图特点6的内容)

除了安全性,JWT还有什么好处吗?

JWT官方给出的解释是(对比SWT与SAML):

JWT由于使用的是JSON所以比较轻量:由于JSON不像XML那么冗长,所以在编码时,它的大小也更小,使得JWT比SAML更紧凑。这使得JWT成为在HTML和HTTP环境中传递的好选择。

安全性:SWT只能使用HMAC算法由共享密钥对称签名。然而,JWT和SAML令牌可以使用X.509证书形式的公钥/私钥对进行签名。与签名JSON的简单性相比,使用XML数字签名签名XML而不引入模糊的安全漏洞是非常困难的。

JSON在各种语言都能方便的解析:JSON解析器在大多数编程语言中都很常见,因为它们直接映射到对象。相反,XML没有自然的文档到对象映射。这使得使用JWT比使用SAML断言更容易。

跨平台性:JWT在互联网规模上使用。这突出了在多个平台(尤其是移动平台)上客户端处理JSON Web令牌的方便性。

参考资料:
基于Session的身份窃取 - 腾讯云开发者社区-腾讯云 (tencent.com)

JSON Web Token 入门教程 - 阮一峰的网络日志 (ruanyifeng.com)

JSON Web Token Introduction - jwt.io

learn-json-web-tokens/README.md at master · dwyl/learn-json-web-tokens (github.com)

你可能感兴趣的:(开发者手册,web,后端)