首页 > 其他分享 >JSON Web Token 入门教程

JSON Web Token 入门教程

时间:2024-03-20 09:23:10浏览次数:24  
标签:Web 请求 验证 入门教程 JWT 认证 JSON Cookie 服务端

本文收录于 Github.com/niumoo/JavaNotes,Java 系列文档,数据结构与算法!
本文收录于网站:https://www.wdbyte.com/,我的公众号:程序猿阿朗

JSON Web TokenJWT)是一种可以在多方之间安全共享数据的开放标准,JWT 数据经过编码和数字签名生成,可以确保其真实性,也因此 JWT 通常用于身份认证。这篇文章会介绍什么是 JWT,JWT 的应用场景以及组成结构,最后分析它的优点及局限性。

传统认证方式的问题

在介绍 JWT 之前,先看下传统认证方式有什么问题,这里的传统认证方式是指 Session-Cookie 方式。有小伙伴可能要说了,传统认证方式能有什么问题,如果有问题肯定是你代码写的不好。其实不是,有些问题存在于方案本身。

先来看一下传统的认证方式流程:

  1. 客户端输入用户名密码,点击登录。
  2. 服务端验证用户名密码,校验通过,服务端存储 Session 数据,如身份,权限。
  3. 服务端响应 Cookie,一般内容是一个 Session ID,客户端收到 Cookie 后存储。
  4. 客户端后续请求携带 Cookie 作为身份认证凭据,服务端验证 Cookie 得知用户身份。

这是常见的认证流程,但是这种认证方式存在下面几个问题。

状态存储负担

Session-Cookie 方式因为服务端要存储当前会话信息,而且必不可少, 这就额外增加了存储负担,而且在分布式系统中,还要考虑不同机器之间的会话状态同步问题。有时还需要部署独立的认证服务。不易维护。

跨域问题

基于 Cookie 会话的认证方式,在进行跨域请求时存在难点,Cookie 不会跟随跨域请求。认证信息带不过去,当然,聪明的小伙伴可以通过设置客户端参数,配置服务端参数等操作来允许跨域,不过有点麻烦了。

CSRF 攻击风险

CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种常见的 Web 安全漏洞。有些小伙伴不知道是什么意思,看下面流程:

  1. 你登录了 QQ 空间,传统认证方式,客户端成功存储了 Cookie。
  2. 你的 “好友X” 给你发了一个链接,标题 “专家:吃淀粉肠活不过三年”。
  3. 突然你感觉仿佛昨晚淀粉肠的香味还没散去,你迫不及待的点开了,没想到自动跳转到了 QQ 空间,你感觉莫名其妙,大失所望,立马关掉。
  4. 但是没想到的是这个跳转请求了空间说说发表接口,因为你之前登录过,Cookie 状态还在。说说直接发表成功了。那马上可能就有好友问你空间发的乱七八糟的内容是什么意思了。

QQ 空间曾经也确实出现过 CSRF 漏洞。

在解决这几个问题上,JWT 具有天然优势,它存储在客户端,服务端无状态。Token 可以不存在 Cookie 中,轻松跨域又减少了 CSRF 风险。

JWT 是什么

JWT(JSON Web Tokens)它定义了一种紧凑自包含的方式用于在各方之间作为 JSON 对象安全地传递信息。紧凑意味着内容尽可能的短小。自包含意味着内容中包含了身份信息。这个信息可以用于身份认证,也可以用于信息交换。由于信息会使用密钥进行数字签名,因此JWT 可以被验证以及信任。

JWT 应用场景

常见的 JWT 应用常见有 JWT 授权和信息交换:

  • 授权:JWT 被应用最多的场景,用户登录后服务端响应一个 JWT,后续的请求都携带 JWT内容,以此验证用户身份。使用 JWT 可以进行单点登录,可以跨域。
  • 信息交换:因为 JWT 需要使用密钥进行签名,因此使用 JWT 安全的传输信息也是一个好方法,签名可以确保消息发送人没有问题,确保消息没有被篡改。

JWT 组成结构

JWT 由小数点分割的三部分组成,如 xxxxx.yyyyy.zzzzz,这三部分对应的是的标头(Header)、负载(Payload)、签名(Signature),每部分使用 Base64Url 进行编码,

下面是一个真实 JWT 示例:

注意:JWT 为紧凑形式,没有换行,这里为了方便阅读,进行了换行。

标头 Header

Header 部分 Base64Url 解码后可以看到两个字段,alg 指定签名算法,typ 指定 Token 类型。

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

对上述标头对象进行 Base64Url 编码以形成 JWT 的第一部分。

负载 Payload

第二部分中存放了实际需要的数据,用户可以自定义内容,如用户身份信息。

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

同时 JWT 也规定了几个官方字段:

iss (issuer):签发人
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
exp (expiration time):过期时间
iat (Issued At):签发时间
jti (JWT ID):编号

可以看到不管第一部分还是第二部分,字段名都是三位字母,这也是为了内容的紧凑。对 JWT 负载进行 Base64Url 编码以形成 JWT 的第二部分。

特别注意:由于只要 Base64Url 解码就可以看到第二部分内容,因此不能在 Payload 中存储敏感信息。

签名 Signature

签名 Signature 的生成依赖标头 Header负载 Payload ,同时要有拥有用于签名的密钥,因此签名可以用于验证 JWT 的发送者是否正确,并确保消息没有被篡改。

Signature = HMACSHA256(
  base64UrlEncode(header) + '.' +
  base64UrlEncode(payload),
  secret)

JWT 官网也提供 JWT 在线解码验证工具,可以访问查看。

JWT 身份认证

使用 JWT 进行身份认证的工作流程如下:

  1. 用户使用登录凭证(如用户名和密码)进行登录。

  2. 服务器验证凭证的正确性,并创建一个包含用户信息的 JWT。

  3. 服务器对 JWT 进行签名,然后将其发送回用户。

  4. 用户将 JWT 存储在客户端(如 localStorage),并在随后的请求中随同发送。

    如添加到请求头:Authorization: Bearer <token>

  5. 服务器在接收到请求后,验证 JWT 的签名并解析其内容,确认用户的身份,然后返回请求的数据。

  6. JWT 可能在一定时间后过期,用户需要重新登录获取新的 JWT。

JWT 的特点

JWT 有下面几个特点。

  1. 紧凑:JWT 设计十分紧凑,结果较小,可以在参数,请求头中传输。
  2. 自包含:JWT 自身包含了用户验证的所需信息,避免了多次查询数据库。
  3. 跨语言:JWT 使用 JSON 格式,现代编程语言都有对 JSON 的支持。
  4. 安全性:JWT 需要使用密钥进行数据签名,密钥不泄露,JWT 就是安全的。但是因为 JWT 自包含和 Base64Url 编码特性,JWT 中的信息可以被直接读取,因此建议使用 HTTPS 协议。如果对安全性要求较高,还可以对 JWT 内容在进行一次加密(如 AES)。
  5. 分布式环境友好:因为 JWT 在服务端无状态,因此 JWT 适用于单点登录,同时可以跨域
  6. 不可撤销:一旦 JWT 签发了,在有效期内将会一直有效,除非服务器增加额外逻辑来强制撤销某个 JWT Token,如黑名单机制。
  7. 性能问题:虽然避免了查询数据库,但是服务器仍需对每个请求中的 JWT 进行解码和验证,如果请求量巨大,这也可能成为性能瓶颈。

JWT 最佳实践

JWT 存在优点,也有很多风险与挑战,参考前人的最佳实践可以少走弯路。

  1. 内容紧凑最小化:最小限度的减少 JWT 负载中的内容,避免存储敏感数据,只存储重要数据。某些服务器不接受大于 8KB 的请求头。
  2. 验证必不可少:每次收到 JWT 都要进行验证,内容验证,过期时间验证。发行者验证。
  3. 使用 JWT 库:不要自己编写 JWT 类库,密码学和安全都是非常复杂的东西,使用专业的类库好过自己编写。
  4. JWT 过期时间:设计合理的过期时间,因为 JWT 一旦颁发,无法删除。过长的有效期存在风险。

总体而言,JWT 提供了一种相对简单且有效的方式来处理身份验证问题,但是需要注意JWT 安全性和细节问题,以确保 JWT 可以在应用中正确且安全地使用。

预告:下一篇文章会介绍如何在 Java 中使用 JWT 进行身份验证。

参考

预告下一篇:Java 中如何使用 JWT 进行身份认证

本文收录于 Github.com/niumoo/JavaNotes,Java 系列文档,数据结构与算法!
本文收录于网站:https://www.wdbyte.com/,我的公众号:程序猿阿朗

标签:Web,请求,验证,入门教程,JWT,认证,JSON,Cookie,服务端
From: https://www.cnblogs.com/niumoo/p/18084435

相关文章

  • websocket相关
    一、websocket相关的计网知识点1.全双工,半双工,单工分别是什么意思它们三个其实指的是都是一种通信模式,是一个抽象概念,单工指的是信息是单通道单向的,信息只能从A传达到B,但是不能由B传达到A。比如广播站和收音机,收音机只能单方面接受广播站的信息。半双工则是单通道双向的,信息可以从......
  • 2024中国行政区域含港澳台【省市区县镇乡村】五级联动地址json数据
    GitHub-657258535/China-Area-Region-Administrative-Divisions:中华人民共和国行政区划:省级(省份)、地级(城市)、县级(区县)、乡级(乡镇街道)、村级(村委会居委会)五级联动地址数据。 中华人民共和国行政区划:省级(省份)、地级(城市)、县级(区县)、乡级(乡镇街道)、村级(村委会居委会)......
  • Solon Web 文件上传的最佳实践
    文件上传是Web开发中最常见的一个应用场景。一般在处理数据时,会有两种常见的方案:直接把文件流放在内存里,或者把文件流先缓冲到磁盘。1、如果是高频且文件极小使用纯内存模式,默认即可。如果高频小文件,是不适合用“临时文件模式”的,磁盘可能容易刷坏。只能多配些内存!2、如果是......
  • buuctf web做题记录 基础sql注入
    buuctf做题记录[SUCTF2019]EasySQL1先考虑堆叠查询1;showdatabases;Array([0]=>1)Array([0]=>ctf)Array([0]=>ctftraining)Array([0]=>information_schema)Array([0]=>mysql)Array([0]=>performance_schema)Array([0]......
  • HTML期末大作业~HTML眼镜网站~Web大学生网页成品-s08
    HTML期末大作业~学生HTML个人网页作业作品下载个人主页博客网页设计制作大学生个人网站作业模板简单个人网页制作,HTML网页设计结课作业↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓http://imianba.cn/#/articles?category=1&theme=0↑↑↑↑↑↑......
  • 使用Selenium执行JavaScript脚本:探索Web自动化的新领域
    前言在我们使用selenium进行自动化测试的时候,selenium能够帮助我们实现元素定位和点击输入等操作,但是有的时候,我们会发现,即使我们的元素定位没有问题,元素也无法执行操作;也有部分情况是我们无法直接定位滚动条河时间控件来进行操作,这个时候,我们就需要借助JavaScript来解决问题。......
  • WebRtc实时音波
    摘要:最近在做音视频相关业务,用的到了webRtc技术,掌握这些方法可以结合业务做,麦克风检测、录制音频,都是可以的;基本操作和其它方法都写好在methods中了;全局变量//后续会创建AnalyserNode对象letanalyser:any=null;//后续赋值canvas标签对象letcanvas:any=nu......
  • vue使用JSWebrtc播放webrtc视频流
    1、下载JSWebrtc.min.js文件地址:https://github.com/kernelj/jswebrtc/tree/master/dist 或者再此路径下载 https://files.cnblogs.com/files/blogs/702532/jswebrtc.min.js?t=1710839018&download=true2、使用jswebrtc2.1文件放到public/static目录下,位置不能放错 2......
  • WebStorm 怎么编译 Vue 工程
    最近一些工程项目,需要用到Vue,只能从头学一下。目前使用的WebStorm,但是不知道怎么编译,还要下载Node.js,对这个不熟悉。最终找到了编译方法:记录一下1.打包方法1.1在工程里面,package.json,点击右键,选择显示npm脚本。然后点击build1.2菜单-->视图-->工具窗口-->npm,然......
  • [极客大挑战 2019]web部分题解(sql部分已完结,其他部分正在更新)
    SQL部分:[极客大挑战2019]BabySQL打开环境后有登录界面◕‿◕一眼注入,后先试试万能密码:username:admin'or'1'='1password:1 GG,出大问题,我就会这一招啊O.o??完结撒花(不是꒰ঌ(⌯''⌯)໒꒱开玩笑的,着看着像是过滤了or后来尝试了一下oorr双写发现也不行,那咱继续注入哈:尝试......