JSON Web令牌(JWT)

参考JWT

JWT与cookie+session的区别

服务器端维护登录状态,使用传统Cookie和Session方案,扩展性不好。而 JSON Web Token(JWT)可实现服务器无状态,扩展性好。

先解释一下单点登录的概念:在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任。单点登录在大型网站里使用得非常频繁,例如像阿里巴巴这样的网站,在网站的背后是成百上千的子系统,用户一次操作或交易可能涉及到几十个子系统的协作,如果每个子系统都需要用户认证,不仅用户会疯掉,各子系统也会为这种重复认证授权的逻辑搞疯掉。

在单点登录的时候,共享登录状态信息的实现有以下两种方案:

  • 方案一:使用session 数据持久化(写入数据库或者Redis中),服务受到请求后,向持久层请求数据,但如果持久层挂了,就会单点失败。
  • 方案二:使用JWT,服务器不保存session数据,所有状态信息都保存在客户端,每次请求都发回服务器。

验证方式

无论session还是token,做用户验证都是不需要用到用户密码的。

session

客户端登录后,第二次访问服务器时,cookie中带有sessionid,服务器在redis中查找是否存在这个sessionid,如果存在,则用户验证成功,并且拿出这个sessionid对应的用户信息。

token

客户端登录后,第二次访问服务器时携带token,服务端接收到 token 之后,会逆向构造过程,decode 出 JWT 的三个部分,这一步可以得到 sign 的算法及 payload,结合服务端配置的 secretKey(只有服务端知道这个密钥),生成 $Signature,与token中的 $Signature 比对以验证 token 是否有效,完成用户身份的认证,验证通过才会使用 payload 的数据。

参考https://zhuanlan.zhihu.com/p/27370773

从上面可以看到,二者的区别就在于,session把用户信息放在服务端,而token把用户信息放在客户端(即token)。

JWT实现原理

客户端首次访问服务器,并且认证成功以后,生成一个json对象,发回给客户端。之后,客户端每次与服务端通信,都回传这个JSON对象。服务器靠这个JSON对象认证用户身份。为防止用户篡改数据,服务器生成这个对象的时候,会加上签名。

使用了JWT后,服务器不再保存任何session数据,实现了服务无状态,从而比较容易实现扩展。

JSON对象具体内容

Header.Payload.Signature

  • Header:经Base64URL算法转成字符串的JSON对象,描述JWT的元数据,如签名算法(默认HMAC SHA256 对称加密)、令牌类型等属性。
  • Payload:经Base64URL算法转成字符串的JSON对象,实际传输的数据,如签发人iss、主题sub、受众aud、过期时间exp、生效时间nbf、签发时间iat、编号jti (7个官方字段)以及自定义私有字段。
  • Signature:对前两部分的签名,指定密钥secret ,对头部以及载荷内容进行签名。如果有人对头部以及载荷的内容解码以后进行修改,再进行编码的话,即时使用相同密钥签名,结果也与原来的不一样。如果不知道服务器加密时候用的秘钥的话,得出来的签名也是不一样的。

截取自JWT官网

Base64URL算法

Base64编码后的字符串中可能包含 + 、/ 和 = 三个字符,在 URL 里面有特殊含义,所以要被替换掉:= 被省略、+ 替换成-,/ 替换成 _ 。这就是 Base64URL 算法。

JWT作为一个令牌(token),有些场景可能会附到URL中(如:api.example.com/?token=xxx),因此需要采用Base64URL 算法将Header 和 Payload 转化为字符串。

JWT优缺点

参考用户认证:基于jwt和session的区别和优缺点

优点

  • 所有状态信息存储在客户端,减轻了服务端压力(不需要存储session)
  • 可扩展性好,应用程序分布式部署的情况下,session需要做多机数据共享,存在数据库或者redis里面。而jwt不需要。
  • JWT不仅可以用于认证,也可以在 JWT 中存储用户权限信息、用户个人信息。有效使用JWT,可以降低服务器查询数据库的次数(用户信息都写在JWT中,不需要访问数据库取用户信息)

缺点:

  • 使用过程中无法废止或修改,签发后到期前始终有效
  • 包含认证信息,泄露后权限被盗用(建议采用较短的有效期,并使用HTTPS协议传输)
  • JWT 的内容(内部的 JSON 数据)通常是不加密的。这意味着,即使没有密钥,也可以查看 JWT 内的数据。JWT 默认并不会加密你的数据,它只是帮助你验证是你信任的一方创建了它。因此jwt中不能存储敏感数据。而session的信息是存在服务端的,相对来说更安全。
  • 由于是无状态使用JWT,所有的数据都被放到JWT里,每一次http请求都会把jwt携带在Header里面,http请求的Header可能比Body还要大,通信开销大。

总结

适合使用jwt的场景:

  • 有效期短
  • 只希望被使用一次

比如,用户注册后发一封邮件让其激活账户,通常邮件中需要有一个链接,这个链接需要具备以下的特性:能够标识用户,该链接具有时效性(通常只允许几小时之内激活),不能被篡改以激活其他可能的账户,一次性的。这种场景就适合使用jwt。

而由于jwt具有一次性的特性。单点登录和会话管理非常不适合用jwt,如果在服务端部署额外的逻辑存储jwt的状态,那还不如使用session。基于session有很多成熟的框架可以开箱即用,但是用jwt还要自己实现逻辑。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值