引言
JWT,即为JSON Web Token,拆开来看,JSON是JavaScript的一种对象数据存储方式,Token则是令牌,组合在一起就是在Web应用上,使用令牌的JSON数据,乍一看还是有点抽象,
举个例子吧,你的产品需要一个卡密来激活,激活之后才可以请请求服务器,但是HTTP请求没办法告诉服务器我是谁,我曾经请求了没,所以每次请求都是全新的,服务器在回答之后相当于“失忆”了,我如何让服务器知道我是谁来确定用户?如果单纯使用前端安全性不高,比如用cookie告诉服务器我是Kevin,服务器觉得是就是,但是我可以改成自己是Elysia,服务器还真以为是Elysia,这样子玩显然行不通,因为用户可以随便更改cookie的信息。
因为篇幅限制,这里就不放太多的业务代码了,再然后提醒一下,本篇内容综合,需要先掌握系统的js知识才能继续往下看,包括不限于:SessionStorage,localstorage,cookie,crypto,JSON对象操作,nodejs
卡密激活场景
接下来就以网站最常见的一种卡密激活的请求的方式举例,某个服务器需要你激活,每次请求都需要携带这个卡密信息才能返回结果。
目前常用的几种方式是Session和JWT
Session
Session相当于一个缓存,当A用户请求服务器之后,服务器会暂时存储A的信息,并返回一个Session token,等到下次A携带这个Session token给服务器的时候,服务器就知道是A用户了,比如存储这个用户卡密到期日期,还有用户基本信息等等,这样服务器处理数据就依靠存储的信息。但是Session也有缺点,因为是存放在服务器端的,每次查找调用都会有点麻烦,而且在多服务器负载均衡的场景下,A用户请求A服务器没问题,但是B服务器有可能因为同步延迟没有同步A服务器的Session数据,导致B服务器不认识A用户了,这样一来服务器压力会变大;并且要实现多平台互通的时候,意味着Session也需要互通,这就需要不同服务器要同时使用一个数据库,加大了数据库的压力。
JWT
JWT更为直接,把压力交给用户,直接把信息存在用户浏览器上,服务器只管解码,但是前面也提到了,直接存用户浏览器上非常不安全,很容易就篡改了,所以JWT在普通JSON数据的基础上,加入了Token这么一个玩意,保证了数据不被篡改。当用户确定开卡的时候,服务器签发一个JWT,上面标记了过期时间,用户ID和基本信息,当用户A请求的时候,就需要携带这个jwt请求服务器,服务器解码验证确定没问题,拿到基本信息处理就完毕,不再像Session那样还需要去找A用户那块Session存储,自然就方便快速很多。
JWT长什么样
数据结构
JWT,长这样
eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJ3aWZlIjoiRWx5c2lhIiwiaXNzIjoiQXItU3ItTmEiLCJzdWIiOiLku4DkuYjmmK9KV1QiLCJuYmYiOjE3MTE4MTQ0MDAsImlhdCI6MTcxMTgxNDQwMH0.dF5bnDx0y_OKMQrKkWYUpDjgW6oD0C1WR_fD4Q16ENJ1Hm7ahxbGcCdMLNJQxOrRMgr7xV0SaL3aoaiEhE_3Ug
这一眼看上去乱七八糟的,不过,数据里面有两个点,数据的部分就是由.来分开的,分别叫做Header 头部,Payload 数据载荷,Signature 签名
上面这段数据的三部分如下:
Header
eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9
Payload
eyJ3aWZlIjoiRWx5c2lhIiwiaXNzIjoiQXItU3ItTmEiLCJzdWIiOiLku4DkuYjmmK9KV1QiLCJuYmYiOjE3MTE4MTQ0MDAsImlhdCI6MTcxMTgxNDQwMH0
Signature
dF5bnDx0y_OKMQrKkWYUpDjgW6oD0C1WR_fD4Q16ENJ1Hm7ahxbGcCdMLNJQxOrRMgr7xV0SaL3aoaiEhE_3Ug
Header和Payload都是由原始数据Base64编码后得到的,但是由于Payload有可能出现base编码后的=符号,而为了兼容浏览器URL地址栏的位置防止被编码,可以描述为:=被省略、+替换成-,/替换成_,所以在编解码的时候需要用到Base64URL的算法。
把它们分别解码就得到了如下数据:
Header
{\”alg\”:\”HS512\”,\”typ\”:\”JWT\”}
Payload
{\”wife\”:\”Elysia\”,\”iss\”:\”Ar-Sr-Na\”,\”sub\”:\”什么是JWT\”,\”nbf\”:1711814400,\”iat\”:1711814400}
这下就明白了为什么JWT的J是JSON了吧
Header
在标准的JWT
评论前必须登录!
注册