通俗易懂讲解Json Web Token (JWT)

 更新时间:2022年12月08日 09:36:18   作者:scluis  
这篇文章主要介绍了通俗易懂讲解Json Web Token (JWT)问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

前言

之前只是了解JWT是对cookie和session的一种升级方案,在前后分离的项目中用的比较多,今天突然好奇,它到底怎么解决session共享的问题的,觉得大概明白后,总结了一下相关知识。

基于session认证所显露的问题

session数据默认是保存在服务器内存中的,而随着认证用户的增多,服务端的开销会明显增大。

因为session是保存在服务器内存中的,在分布式的应用上,不能保证每次都请求到同一台服务器,相应的限制了负载均衡的能力,只能通过服务器之间的session共享解决问题。

session是基于cookie来进行用户识别的, cookie如果被截获,用户就会很容易受到**跨站请求伪造(CSRF)**的攻击。

组成

Token由三部分组成:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.UQmqAUhUrpDVV2ST7mZKyLTomVfg7sYkEjmdDI5XF8Q

第一部分为头部(header),其中包含了签名的加密算法

第二部分为载荷(payload, 类似于飞机上承载的物品),用来保存用户的相关信息

第三部分是签名(signature),用来验证token是否被篡改过

header

jwt的头部承载两部分信息:

  • 声明类型,这里是jwt
  • 声明签名的加密算法 通常直接使用 HMAC SHA256

完整的头部就像下面这样的JSON:

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

然后将头部进行base64加密(该加密是可以对称解密的),构成了第一部分

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

playload

包含三个部分:

  • 标准中注册的声明
  • 公共的声明
  • 私有的声明

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

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

公共的声明 :

公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息。但不建议添加敏感信息,因为该部分在客户端可解密。

私有的声明 :

私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。

payload示例:

{  "sub": "1234567890",  "name": "John Doe",  "admin": true}

然后将其进行base64加密,得到Jwt的第二部分

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

signature

jwt的第三部分token签名,它通过base64加密后的header和payload生成。

服务端将base64加密后的header和payload使用.连接组成一个字符串(头部在前),然后通过header中声明的签名加密方式使用secret密钥加密,就构成了jwt的第三部分。

如果header和payload的内容被修改过,生成的签名就会是不同的(可以理解成不同内容的哈希值不一样),从而达到判断token是否是被篡改过的效果。

签名示例:

UQmqAUhUrpDVV2ST7mZKyLTomVfg7sYkEjmdDI5XF8Q

密钥secret是保存在服务端的,服务端会根据这个密钥进行生成token和验证,需要保护好,不能泄漏。

验证过程

服务器应用在接受到JWT后,会首先对头部和载荷的内容用同一算法再次进行签名。

如果服务器应用对头部和载荷再次以同样方法签名之后发现,自己计算出来的签名和接受到的签名不一样,那么就说明这个Token的内容被篡改过,否则就完成了验证。

那么服务器应用是怎么知道我们用的是哪一种算法进行的签名的呢?JWT的头部中已经用alg字段指明了我们的签名加密算法了。

基于token的鉴权机制

  • 用户使用用户名密码来请求服务器
  • 服务器进行验证用户的信息
  • 服务器通过验证发送给用户一个token
  • 客户端存储token,并在每次请求时附送上这个token值
  • 服务端验证token值,并返回数据

优点

  • 支持跨域访问: Cookie是不允许垮域访问的,Token机制不基于Cookie实现,可以跨域访问。
  • 服务端无状态,可扩展性好: Token机制在服务端不需要存储session信息,因为Token 自身包含了所有登录用户的信息,服务端只需要进行token验证即可。
  • 更安全:Token不基于Cookie实现,不会出现Cookie劫持所导致的安全问题。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Bootstrap模态框案例解析

    Bootstrap模态框案例解析

    这篇文章主要介绍了Bootstrap模态框案例解析,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-03-03
  • JS库 Highlightjs 添加代码行号的实现代码

    JS库 Highlightjs 添加代码行号的实现代码

    Highlightjs是一款优秀的代码高亮Js组件,可以很方便地对各种语言编写的代码添加语法高亮样式。本文重点给大家介绍Highlightjs 添加代码行号的实现代码,需要的朋友参考下吧
    2017-09-09
  • js实现导入导出功能实例代码(FileSave.js)

    js实现导入导出功能实例代码(FileSave.js)

    这篇文章主要给大家介绍了关于js实现导入导出功能(FileSave.js)的相关资料,FileSaver.js是在客户端保存文件的解决方案,非常适合在客户端上生成文件的Web应用,需要的朋友可以参考下
    2023-11-11
  • 使用JS实现抖音上很火的圣诞树的示例代码

    使用JS实现抖音上很火的圣诞树的示例代码

    圣诞节快到了,经常会在抖音上刷到圣诞树的视频,所以本文小编给大家介绍了如何使用JS实现圣诞树,文章通过代码示例给大家介绍的非常详细,感兴趣的小伙伴跟着小编一起来看看吧
    2023-12-12
  • Express代理转发服务器实现

    Express代理转发服务器实现

    这篇文章主要为大家介绍了Express代理转发服务器实现技巧详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • js使用for循环及if语句判断多个一样的name

    js使用for循环及if语句判断多个一样的name

    这篇文章主要介绍了js使用for循环机if语句判断多个一样的name,此法比较实用,需要的朋友可以参考下
    2014-09-09
  • Javascript执行上下文顺序的深入讲解

    Javascript执行上下文顺序的深入讲解

    这篇文章主要给大家介绍了关于Javascript执行上下文顺序的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • javascript实现日历效果

    javascript实现日历效果

    这篇文章主要为大家详细介绍了javascript实现日历效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-06-06
  • javascript封装简单实现方法

    javascript封装简单实现方法

    这篇文章主要介绍了javascript封装简单实现方法,涉及javascript中方法与属性的相关设置与使用技巧,非常简单实用,需要的朋友可以参考下
    2015-08-08
  • dwr spring的集成实现代码

    dwr spring的集成实现代码

    需正确使用new和spring,注意两者的区别
    2009-03-03

最新评论