JWT初学者教程

一、简介

1、什么是JWT

JWT(JSON Web Token)是一个开放标准(RFC 7519),它定义了一种紧凑且独立的方式,可以在各方之间作为JSON对象安全地传输信息。此信息可以通过数字签名进行验证和信任。JWT可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对进行签名。

也就是通过JSON形式作为 Web应用中的令牌,用于在各方之间安全的将信息作为JSON对象传输。在数据传输过程中还可以完成数据加密、签名等相关处理。

2、什么时候应该用JWT

下列场景中使用JSON Web Token是很有用的:

  • Authorization (授权) : 这是使用JWT的最常见场景。一旦用户登录,后续每个请求都将包含JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是现在广泛使用的JWT的一个特性,因为它的开销很小,并且可以轻松地跨域使用。

  • Information Exchange (信息交换) : 对于安全的在各方之间传输信息而言,JSON Web Tokens无疑是一种很好的方式。因为JWT可以被签名,例如,用公钥/私钥对,你可以确定发送人就是它们所说的那个人。另外,由于签名是使用头和有效负载计算的,您还可以验证内容没有被篡改。

3、为什么使用JWT?

我们先看一下传统的认证方式

HTTP协议是无状态的,也就是说,如果我们已经认证了一个用户,那么他下一次请求的时候,服务器不知道我是谁,我们必须再次认证

传统的做法是将已经认证过的用户信息存储在服务器上,比如Session。用户下次请求的时候带着Session ID,然后服务器以此检查用户是否认证过。

session 认证:

用户第一次请求服务器的时候,服务器根据用户提交的相关信息,创建对应的 Session
​
请求返回时将此 Session 的唯一标识信息 SessionID 返回给浏览器
​
浏览器接收到服务器返回的 SessionID 信息后,会将此信息存入到 Cookie 中,同时 Cookie 记录此 SessionID 属于哪个域名
​
当用户第二次访问服务器的时候,请求会自动判断此域名下是否存在 Cookie 信息,如果存在自动将 Cookie 信息也发送给服务端,服务端会从 Cookie 中获取 SessionID,再根据 SessionID 查找对应的 Session 信息,如果没有找到说明用户没有登录或者登录失效,如果找到 Session 证明用户已经登录可执行后面操作。

 

根据以上流程可知,SessionID 是连接 Cookie 和 Session 的一道桥梁,大部分系统也是根据此原理来验证用户登录状态。

session认证暴露的问题

1、每次用户认证通过以后,服务器需要创建一条记录保存用户信息,通常是在内存中,随着认证通过的用户越来越多,服务器的在这里的开销就会越来越大。
2、用户认证之后,服务端做认证记录,如果认证的记录保存在内存中,这意味着用户下次请求还需请求在这台服务器上,这样才能拿到授权的资源,这样在分布式的应用上,相应限制了负载均衡的能力。这也意味着限制了应用的扩展能力。
3、因为是基于cookie来进行用户识别的,cookie如果被截获,用户就会很容易受到跨站请求伪造的攻击
cookie+session这种模式通常是保存在内存中,而且服务从单服务到多服务会面临的session共享问题,随着用户量的增多,开销就会越大。而JWT只需要服务端生成token,客户端保存这个token,每次请求携带这个token,服务端认证解析即可。

4、JWT认证流程和特点

认证流程:

前端将用户的登录信息发送给服务器;
服务器接受请求后为用户生成独一无二的认证信息--token,传给客户端浏览器;
客户端将token保存在cookie或者storage中;
在之后访问客户端都携带这个token请求服务器;
服务器验证token的值,如果验证成功则给客户端返回数据。

 

特点:

1)三部分组成,每一部分都进行字符串的转化
2)解密的时候没有使用数据库,仅仅使用的是secret进行解密
3)JWT的secret千万不能泄密!

5、JWT的组成

JWT的组成分为三部分,它们之间用圆点(.)连接

Header      头部
Payload     载荷
Signature   签名

Header(头部)

header部分,即头信息,包含两部分,alg:算法名称、typ:token的类型

{
    'alg':"HS256",
    'typ':"JWT"
}

将头部使用base64编码加密,构成第一部分

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Payload(载荷)

载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包含三个部分

标准中注册的声明 (建议但不强制使用) :

iss: jwt签发者
sub: jwt所面向的用户
aud: 接收jwt的一方
exp: jwt的过期时间,这个过期时间必须要大于签发时间
nbf: 定义在什么时间之前,该jwt都是不可用的.
iat: jwt的签发时间
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

存放传输的数据

{
    'name':"name"
    'state':true
}

对于签名令牌,此信息虽然可以防止篡改,但任何人都可以读取。除非加密,否则不要将敏感信息放入到Payload或Header元素中。

Payload中放传输的信息,用户信息等用于传输的信息。Playload部分的JSON使用base64编码加密,形成JWT的第二部分。

eyJzdWIiOiJ0b2tlbl9kZW1vIiwiaXNzIjoiU0VSVklDRSIsIm5hbWUiOiJ4eXgiLCJleHAiOjE2Mjk1Mzk0MzMsImlhdCI6MTYyOTQ1MzAzMywidXNlcklkIjoyMX0

Signature(签名)

这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行secret组合加密,然后就构成了jwt的第三部分

如:HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

将这三部分用.连接,组成了一个JWT

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0b2tlbl9kZW1vIiwiaXNzIjoiU0VSVklDRSIsIm5hbWUiOiJ4eXgiLCJleHAiOjE2Mjk1Mzk0MzMsImlhdCI6MTYyOTQ1MzAzMywidXNlcklkIjoyMX0.91uTZ1O7Pt_st_UKBlTseMJe3ZlSu027mrv4Admo1u8

6、JWT优缺点

优点:

①. 可扩展性好
应用程序分布式部署的情况下,Session需要做多机数据共享,通常可以存在数据库或者Redis里面。而JWT不需要。
​
②. 无状态
JWT不在服务端存储任何状态。RESTful API的原则之一是无状态,发出请求时,总会返回带有参数的响应,不会产生附加影响。用户的认证状态引入这种附加影响,这破坏了这一原则。另外JWT的载荷中可以存储一些常用信息,用于交换信息,有效地使用 JWT,可以降低服务器查询数据库的次数。

缺点:

① 安全性:由于JWT的payload是使用Base64编码的,并没有加密,因此JWT中不能存储敏感数据。而Session的信息是存在服务端的,相对来说更安全。
​
② 性能:JWT太长。由于是无状态使用JWT,所有的数据都被放到JWT里,如果还要进行一些数据交换,那载荷会更大,经过编码之后导致JWT非常长,Cookie的限制大小一般是4k,cookie很可能放不下,所以JWT一般放在LocalStorage里面。并且用户在系统中的每一次Http请求都会把JWT携带在Header里面,Http请求的Header可能比Body
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

景元昊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值