转载: Cookie、Session、Token、JWT,一次聊透!
前言 🔖
先跟大家讲清楚,为什么需要这几样东西。
因为HTTP是一种无状态协议,用户每发起一次请求,对于服务器端都是一个完全独立的、全新的请求,你是谁,你之前做过什么操作,都是一无所知的。
就像你去某个电商平台买东西,从商品列表页到商品详情页需要登录一次,从商品详情页把商品加入到购物车还得登录,这对用户来讲是完全无法接受的,所以才诞生了Cookie。
我们可以将Cookie理解为存储在浏览器端的一份数据,这份数据是服务器端发送给浏览器端的。
在后续的请求中,浏览器端的用户每往服务器端发起一次请求,都会携带这份数据进行身份识别验证,这样就不需要重复进行用户名、密码登录了。我们可以看下Cookie的详细交互流程。

从这里来看,Cookie确实很好地解决了HTTP无状态的问题,但它也存在一个巨大隐患,那就是userID之类的关键数据直接存在浏览器端,系统就没有安全性而言了。
用户完全可以把userID从123456改为123457、123458,这样就摇身一变,拥有了其他用户的权限。为了解决该问题,Session也就产生了。
Session直接将用户身份信息,也就是UserID=123456存储在服务器端,然后给浏览器端返回一个自生成的Session ID,并存储在浏览器端的Cookie中。
大家可以这样理解,纯Cookie的方式相当于浏览器端的用户直接说“我是某某某”,然后服务器端就直接相信了。
而Session + Cookie相结合的方式则是浏览器端的用户说“暗语”,服务器端以识别暗语的方式确认“用户是某某某”,这样就大幅提升了系统安全性的问题。我们可以看下Session + Cookie的详细交互流程。

这种方式确实可以运用在生产环境上的、很成熟的方式,但它的弊端在于服务器端需要对Session ID进行存储。
如果存储在Redis中,那Redis宕机就会出现系统不可用的情况,如果存储在数据库中,高频访问又会对数据库造成压力。因此,又出现了仅需验证签名,不需要进行数据存储的Token方式。
Token可以理解为,服务器端给浏览器端签发的数字令牌,浏览器端用户的每次请求都带上这个令牌,服务器端可以通过它来进行身份认证,就像我们进入公园的时候,需要出示门票一样。
当然,Token也可以存储在浏览器端的Cookie中。我们可以看下Token + Cookie的详细交互流程。

最后,咱们再聊一下JWT(JSON Web Token),是Token目前最流行的一种规范,包含Header、Payload(用户信息)和Signature(防伪签名)三个部分,以此来实现无状态身份验证。
原始的、Base64编码前的JSON串类似于这样,我们可以看一下。


由于userID、过期时间等数据已经保存在Token中了,所以服务器端并不需要存储任何数据。
当浏览器端的用户发起请求时,拿到Token直接进行base64_decode,就能获取到数据userID和过期时间,而且进行签名的数据也不用担心被篡改,这样就做到了真正意义上的“无状态”。
讲到这里,大家应该完全理解Cookie、Session、Token、JWT这四个术语了吧。