OAuth2与JWT的区别JWT的适用场景及好处(九)

写在前面:各位看到此博客的小伙伴,如有不对的地方请及时通过私信我或者评论此博客的方式指出,以免误人子弟。多谢!如果我的博客对你有帮助,欢迎进行评论✏️✏️、点赞👍👍、收藏⭐️⭐️,满足一下我的虚荣心💖🙏🙏🙏 。

目录

什么是JWT

为什么用JWT

JWT组成

Session存储

什么是无(无)状态

对称加密与非对称加密

对称加密

非对称加密

场景


什么是JWT

   在这之前我们已经完成了使用springcloud+oauth2进行授权的简单使用,相信小伙伴们跟我一样经常听周围的大佬们提到JWT,那什么是JWT呢,去官网看下 https://jwt.io,百度翻译过来就是

为什么用JWT

之前我们用oauth2不是好好的吗,为什么要用jwt呢,从网上看到有大佬这么说的:

  OAuth2中使用token验证用户登录合法性,但token最大的问题是不携带用户信息,资源服务器无法在本地进行验证,每次对于资源的访问,资源服务器都需要向认证服务器发起请求,一是验证token的有效性,二是获取token对应的用户信息。如果有大量的此类请求,无疑处理效率是很低,且认证服务器会变成一个中心节点,这在分布式架构下很影响性能。

相对OAuth2的好处:

1、通过验证签名,对于token的验证可以直接在资源服务器本地完成,不需要连接认证服务器;

2、在payload中可以包含用户相关信息,这样就轻松实现了token和用户信息的绑定; 

JWT组成

从本质上来说,jwt和OAuth2没有可比性。普通的oauth2颁发的就是一串随机hash字符串,本身无意义,而jwt使用一种特殊格式的token,token是有特定含义的,因为他可以携带自定义的信息。

组成分为如下三部分:

-头部Header:头部包含了两部分,token 类型和采用的加密算法。
-载荷Payload:这部分才是重要的,可以自定义信息保存在此。
-签名Signature:使用编码后的header和payload以及我们提供的一个密钥,然后使用header中指定的签名算法进行签名,签名的作用是保证JWT没有被篡改过,如果有人对头部以及负载的内容解码之后进行修改,再进行编码,最后加上之前的签名组合形成新的JWT的话,那么服务器端会判断出新的头部和负载形成的签名和JWT附带上的签名是不一样的。如果要对新的头部和负载进行签名,在不知道服务器加密时用的密钥的话,得出来的签名也是不一样的。

这三部分均用base64进行编码,并使用.进行分隔。一个典型的jwt格式的token类似xxxxx.yyyyy.zzzzz。 

注意,但是Base64是可逆的,所以注意在Payload部分不要携带敏感信息。

Session存储

Session存储的缺点:

Session方式存储用户id的最大弊病在于Session是存储在服务器端的,服务端保存用户状态,无法进行水平扩展,并且需要占用大量服务器内存。而JWT方式将用户状态分散到了客户端中,可以明显减轻服务端的内存压力。除了用户id之外,还可以存储其他的和用户相关的信息,例如该用户是否是管理员、用户所在的分组等。

相对Session的好处:

1、可以通过URL, POST 参数或者在 HTTP header 发送,因为数据量小,传输速度快。

2、自包含,负载中包含了所有用户所需要的信息,避免了多次查询数据库,服务端也不需要存储 session 信息,做到了服务端无状态。

3、JWT方式将用户状态分散到了客户端中,可以明显减轻服务端的内存压力。除了用户id之外,还可以存储其他的和用户相关的信息,例如该用户是否是管理员、用户所在的分组等。

另外JWT能轻松的实现单点登录,因为用户的状态已经被传送到了客户端。支持移动设备,支持跨程序调用,Cookie 是不允许垮域访问的,而 Token 则不存在这个问题。因为有签名,所以JWT可以防止被篡改。

什么是无(无)状态

说到无状态先说一下有状态,有状态服务,即服务端需要记录每次会话的客户端信息,从而识别客户端身份,根据用户身份进行请求的处理,如session,使用session的缺点前面已经说了,1.服务端保存大量数据,增加服务端压力,2.服务端保存用户状态,无法任意进行水平扩展,需要做session同步,相对于有状态,jwt的无状态的好处也相对于有状态的不足,1.减小服务端存储压力,2.服务端可以任意的迁移和伸缩。而微服务集群中的每个服务,对外提供的都是Rest风格的接口。而Rest风格的一个最重要的规范就是:服务的无状态性(1.服务端不保存任何客户端请求者信息 2.客户端的每次请求必须具备自描述信息,通过这些信息识别客户端身份),这也是无状态的token,jwt在微服务中广泛使用的原因吧。

对称加密与非对称加密

对称加密

加密和解密使用同一个秘钥。

优点:

算法公开、计算量小、加密速度快、加密效率高

缺点:

在数据传送前,发送方和接收方必须商定好秘钥,然后 使双方都能保存好秘钥。其次如果一方的秘钥被泄露,那么加密信息也就不安全了。另外,还需要对密钥进行管理也挺麻烦。

非对称加密

加密和解密使用不同的密钥,一把作为公开的公钥,另一把作为私钥,公开密钥和私有密钥是一对,公钥加密的信息,只有用对应的私钥才能解密,同样的,使用私钥对数据加密,那么只有使用对应的公钥才能解密。说的通俗一点:甲方生成一对密钥并将其中的一把作为公用密钥向其它方公开;得到该公用密钥的乙方使用该密钥对机密信息进行加密后再发送给甲方;甲方再用自己保存的另一把专用密钥对加密后的信息进行解密。甲方只能用其专用密钥解密由其公用密钥加密后的任何信息。

场景

适用场景:
一次性的身份认证、api的鉴权等,这些场景能充分发挥jwt无状态以及分布式验证的优势。

不适用的场景:
jwt因为其无状态和分布式,事实上只要在有效期内,是无法作废的,用户的签退更多是一个客户端的签退,服务端token仍然有效,你只要使用这个token,仍然可以登陆系统。另外一个问题是续签问题,使用token,无疑令续签变得十分麻烦,当然你也可以通过redis去记录token状态,并在用户访问后更新这个状态,但这就是硬生生把jwt的无状态搞成有状态了,而这些在传统的session+cookie机制中都是不需要去考虑的。

另外看网上的博客,在使用jwt是引入的包也是五花八门,其中使用java-jwt的最多,看到一篇文档介绍Java JWT 类库对比及使用,感兴趣的可以的小伙伴可以看下Java JWT 类库对比及使用 - 简书,我接下来学习jwt的时候可能会使用nimbus-jose-jwt这个依赖,虽然有人这么说:

至于为什么使用,因为我不擅长研究,公司有个项目使用的就是nimbus-jose-jwt这个依赖包,估计我可以参考下代码吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值