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

这就是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
JWT 的原理
服务器认证以后,生成一个 JSON 对象,发回给用户,就像下面这样。

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

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

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

写成一行,就是下面的样子。
![]()

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

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

注意,JWT 默认是不加密的,任何人都可以读到,所以不要把秘密信息放在这个部分。
Signature 部分是对前两部分的签名,防止数据篡改。
JWT的使用方式
客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage。
此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息Authorization字段里面。
![]()
另一种做法是,跨域的时候,JWT 就放在 POST 请求的数据体里面。
JWT的特点

说完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)



















