资讯-淘券派

【实践篇】教你玩转JWT认证---从一个优惠券聊起

引言

最近面试过程中,无意中跟候选人聊到了JWT相关的东西,也就联想到我自己关于JWT落地过的那些项目。

关于JWT,可以说是分布式系统下的一个利器,我在我的很多项目实践中,认证系统的第一选择都是JWT。它的优势会让你欲罢不能,就像你领优惠券一样。

大家回忆一下一个场景,如果你和你的女朋友想吃某江家的烤鱼了,你会怎么做呢?

传统的时代,我想场景是这样的:我们走进一家某江家餐厅,会被服务员引导一个桌子,然后我们开始点餐,服务原会记录我们点餐信息,然后在送到后厨去。这个过程中,那个餐桌就相当于session,而我们的点餐信息回记录到这个session之中,然后送到后厨。这个是一个典型的基于session的认证过程。但我们也发现了它的弊端,就是基于session的这种认证,对服务器强依赖,而且信息都是存储在服务器之上,灵活性和扩展性大大降低。

而互联网时代,大众点评、美团、饿了么给了我们另一个选择,我们可能第一时间会在这些平台上搜索江边城外的优惠券,这个优惠券中可能会描述着两人实惠套餐明细。这张优惠券就是我们的 JWT,我们可以在任何一家有参与优惠活动的餐厅使用这张优惠券,而不必被限制在同一家餐厅。同时这张优惠券中直接记录了我们的点餐明细,等我们到了餐厅,只需要将优惠券二维码告知服务员,服务员就会给我们端上我们想要的食物。

好了,以上只是一个小例子,其实只是想说明一下JWT相较于传统的基于session的认证框架的优势。

JWT 的优势在于它可以跨域、跨服务器使用,而 Session 则只能在本域名下使用。而且,JWT 不需要在服务端保存用户的信息,只需要在客户端保存即可,这减轻了服务端的负担。这一点在分布式架构下优势还是很明显的。

什么是JWT

说了这么多,如何定义JWT呢?

JWT(JSON Web Token)是一种用于在网络应用中进行身份验证的开放标准(RFC7519)。它可以安全地在用户和服务器之间传输信息,因为它使用数字签名来验证数据的完整性和真实性。

JWT包含三个部分:头部、载荷和签名。头部包含算法和类型信息,载荷包含用户的信息,签名用于验证数据的完整性和真实性。

额外说一下poload,也就是负荷部分,这块是jwt的核心模块,它内部包括一些声明(claims)。声明由三个类型组成:

Registered Claims:这是预定义的声明名称,主要包括以下几种:

  • iss:Token 发行者
  • sub:Token 主题
  • aud:Token的受众
  • exp:Token 过期时间
  • iat:Token发行时间
  • jti:Token唯一标识符

Public Claims:公共声明是自己定义的声明名称,以避免冲突。

Private Claims:私有声明与公共声明类似,不同之处在于它是用于在双方之间共享信息的。

当用户登录时,服务器将生成一个JWT,并将其作为响应返回给客户端。客户端将在后续的请求中发送此JWT。服务器将使用相同的密钥验证JWT的签名,并从载荷中获取用户信息。如果签名验证通过并且用户信息有效,则服务器将允许请求继续进行。

JWT优点

JWT优点如果我们系统的总结一下, 如下: