一、什么是 JWT?

JWT (JSON Web Token) 是目前最流行的跨域认证解决方案,是一种基于 Token 的认证授权机制。 从 JWT 的全称可以看出,JWT 本身也是 Token,一种规范化之后的 JSON 结构的 Token。

JWT 自身包含了身份验证所需要的所有信息,因此,我们的服务器不需要存储 Session 信息。这显然增加了系统的可用性和伸缩性,大大减轻了服务端的压力。

可以看出,JWT 更符合设计 RESTful API 时的「Stateless(无状态)」原则 。

并且, 使用 JWT 认证可以有效避免 CSRF 攻击,因为 JWT 一般是存在在 localStorage 中,使用 JWT 进行身份验证的过程中是不会涉及到 Cookie 的。

二、JWT 由哪些部分组成?

JWT 本质上就是一组字串,通过(.)切分成三个为 Base64 编码的部分:

  • Header : 描述 JWT 的元数据,定义了生成签名的算法以及 Token 的类型。
  • Payload : 用来存放实际需要传递的数据
  • Signature(签名) :服务器通过 Payload、Header 和一个密钥(Secret)使用 Header 里面指定的签名算法(默认是 HMAC SHA256)生成。

JWT 通常是这样的:xxxxx.yyyyy.zzzzz

示例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Header 和 Payload 都是 JSON 格式的数据,Signature 由 Payload、Header 和 Secret(密钥)通过特定的计算公式和加密算法得到。

Header

Header 通常由两部分组成:

  • typ(Type):令牌类型,也就是 JWT。
  • alg(Algorithm) :签名算法,比如 HS256。

示例:

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

JSON 形式的 Header 被转换成 Base64 编码,成为 JWT 的第一部分。

#Payload

Payload 也是 JSON 格式数据,其中包含了 Claims(声明,包含 JWT 的相关信息)。

Claims 分为三种类型:

  • Registered Claims(注册声明) :预定义的一些声明,建议使用,但不是强制性的。
  • Public Claims(公有声明) :JWT 签发方可以自定义的声明,但是为了避免冲突,应该在 IANA JSON Web Token Registryopen in new window 中定义它们。
  • Private Claims(私有声明) :JWT 签发方因为项目需要而自定义的声明,更符合实际项目场景使用。

下面是一些常见的注册声明:

  • iss(issuer):JWT 签发方。
  • iat(issued at time):JWT 签发时间。
  • sub(subject):JWT 主题。
  • aud(audience):JWT 接收方。
  • exp(expiration time):JWT 的过期时间。
  • nbf(not before time):JWT 生效时间,早于该定义的时间的 JWT 不能被接受处理。
  • jti(JWT ID):JWT 唯一标识。

示例:

{"uid": "ff1212f5-d8d1-4496-bf41-d2dda73de19a","sub": "1234567890","name": "John Doe","exp": 15323232,"iat": 1516239022,"scope": ["admin", "user"]
}

Payload 部分默认是不加密的,一定不要将隐私信息存放在 Payload 当中!!!

JSON 形式的 Payload 被转换成 Base64 编码,成为 JWT 的第二部分。

#Signature

Signature 部分是对前两部分的签名,作用是防止 JWT(主要是 payload) 被篡改。

这个签名的生成需要用到:

  • Header + Payload。
  • 存放在服务端的密钥(一定不要泄露出去)。
  • 签名算法。

签名的计算公式如下:

HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)

算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,这个字符串就是 JWT 。

三、如何基于 JWT 进行身份验证?

在基于 JWT 进行身份验证的的应用程序中,服务器通过 Payload、Header 和 Secret(密钥)创建 JWT 并将 JWT 发送给客户端。客户端接收到 JWT 之后,会将其保存在 Cookie 或者 localStorage 里面,以后客户端发出的所有请求都会携带这个令牌。

简化后的步骤如下:

  1. 用户向服务器发送用户名、密码以及验证码用于登陆系统。
  2. 如果用户用户名、密码以及验证码校验正确的话,服务端会返回已经签名的 Token,也就是 JWT。
  3. 用户以后每次向后端发请求都在 Header 中带上这个 JWT 。
  4. 服务端检查 JWT 并从中获取用户相关信息。

两点建议:

  1. 建议将 JWT 存放在 localStorage 中,放在 Cookie 中会有 CSRF 风险。
  2. 请求服务端并携带 JWT 的常见做法是将其放在 HTTP Header 的 Authorization 字段中(Authorization: Bearer Token)。

四、如何防止 JWT 被篡改?

有了签名之后,即使 JWT 被泄露或者解惑,黑客也没办法同时篡改 Signature 、Header 、Payload。

这是为什么呢?因为服务端拿到 JWT 之后,会解析出其中包含的 Header、Payload 以及 Signature 。服务端会根据 Header、Payload、密钥再次生成一个 Signature。拿新生成的 Signature 和 JWT 中的 Signature 作对比,如果一样就说明 Header 和 Payload 没有被修改。

不过,如果服务端的秘钥也被泄露的话,黑客就可以同时篡改 Signature 、Header 、Payload 了。黑客直接修改了 Header 和 Payload 之后,再重新生成一个 Signature 就可以了。

密钥一定保管好,一定不要泄露出去。JWT 安全的核心在于签名,签名安全的核心在密钥。

五、如何加强 JWT 的安全性?

  1. 使用安全系数高的加密算法。
  2. 使用成熟的开源库,没必要造轮子。
  3. JWT 存放在 localStorage 中而不是 Cookie 中,避免 CSRF 风险。
  4. 一定不要将隐私信息存放在 Payload 当中。
  5. 密钥一定保管好,一定不要泄露出去。JWT 安全的核心在于签名,签名安全的核心在密钥。
  6. Payload 要加入 exp (JWT 的过期时间),永久有效的 JWT 不合理。并且,JWT 的过期时间不易过长。
  7. ......

猿创征文|laravel中JWT的使用相关推荐

  1. 猿创征文|pycharm中的翻译插件translation以及将其更换为百度翻译获取ID和密钥的详细步骤

             我们在用python时有时候遇到一些英语单词,一时忘记了或者从来没见过,这个时候我们就需要百度或者其他途径去查单词的意思,很麻烦,那么能不能像专门的英语软件一样用鼠标一点就可以知道它 ...

  2. 猿创征文|项目中使用Git,解决一些项目开发中常见的Git问题

    写在前面:Git的教程在网上很多,但我在最开始接触项目中需要用Git命令时,发现网上的教程并没有统一的答案告诉我,我到底该输入什么命令,什么又不需要

  3. 猿创征文|服务器中常用的几个资源监控工具整理

    系统级性能优化通常包括两个阶段:性能剖析(performance profiling)和代码优化.性能剖析的目标是寻找性能瓶颈,查找引发性能问题的原因及热点代码.代码优化的目标是针对具体性能问题而优化 ...

  4. 猿创征文|工作中遇到技术盲区后的自我成长

    猿创征文|工作中遇到技术盲区后的自我成长 1.立场 我是一名python后端开发程序员,在一家创业公司中兢兢业业工作快两年了,从软件架构.开发.测试.部署.运维一手经办,到开发文档.API接口.开发周 ...

  5. 猿创征文 | DevOps运维的10个日常使用工具分享

    猿创征文 | DevOps运维的10个日常使用工具分享 一.DevOps介绍 1.DevOps的简介 2.个人分享的10个工具导航 二.jenkins 1.jenkins介绍 2.jenkins的优点 ...

  6. 猿创征文|我的前端学习之旅【来自一名大四老学长的真情流露】

    猿创征文 | 我的前端学习之旅 自我介绍 我浑噩的大一大二(是不是另一个你) 我的大三生活 大三上(学习过程.学习方法.推荐网站) 大三下(技术提升.荣誉证书.推荐比赛) 我与 CSDN 的机缘(从小 ...

  7. 猿创征文|收到谷歌开发者大会正式邀请(Java学生的自学之路)

    文章目录 一.前言 二.收到谷歌邮件 三.感想 四.学习之路 1. 坚持看网课并整理笔记 2.勤加练习 3.坚持总结 4.刷题技巧 5.心态调整 五.结语 一.前言 上一次通过了CSDN内部筛选后,在 ...

  8. 猿创征文|《Java》关键字大全-小结

    目录 关键字 一.Java中的关键字有: 二.访问控制 1.public 2.protected: 3.private: 三.类.方法.变量.修饰符 1.abstract: 2.class: 3.ex ...

  9. 猿创征文丨深度学习基于双向LSTM模型完成文本分类任务

    大家好,我是猿童学,本期猿创征文的第三期,也是最后一期,给大家带来神经网络中的循环神经网络案例,基于双向LSTM模型完成文本分类任务,数据集来自kaggle,对电影评论进行文本分类. 电影评论可以蕴含 ...

最新文章

  1. 【HDU】3441 Rotation
  2. getsockname和getpeername
  3. 机器学习理论篇:机器学习的数学基础
  4. Hama笔记:Unable to load native-hadoop library 和 Snappy native library not loaded 的解决
  5. 笔记-中项案例题-2018年下-整体管理
  6. web服务器虚拟,虚拟web服务器
  7. 问题 I: 连通块计数
  8. python宏替换_简单的宏替换
  9. QUdpSocket 4.6 严重丢包
  10. html——inline、block与block-inline区别
  11. python酒店评论分析_酒店评论的情感分析
  12. pytorch可视化实例:gradcam在resnet18上的应用(快餐式代码教程)
  13. linux使用触摸屏驱动程序,Linux触摸屏驱动
  14. android 极光推送教程 视频教程,Android 极光推送教程
  15. Tampermonkey油猴插件——安装与使用教程
  16. html链接位置移动,锚点链接点击缓慢移动到目标位置
  17. Worthington核心酶——木瓜蛋白酶的特征及相关应用
  18. The Joel Test:Joel 用来评价软件开发团队成熟度的12个问题
  19. 转载:SRT传输库评估报告(V1.0.0)
  20. css+html中div和img对齐

热门文章

  1. C++——set基本操作总结
  2. 刀片服务器的故障信息,刀片服务器故障
  3. 运维体系建设(第二章)
  4. 浏览器打开服务器上的图片无法显示,网页中的图片打不开怎么办?原因与解决办法...
  5. 最全的百度网盘搜索引擎
  6. “信息系统灾难恢复方案设计”大赛
  7. 万众电子期刊在线阅读系统(awd复现)
  8. PWM脉冲宽度调制,实现呼吸灯_领航者开发板
  9. 区块链、NFT与元宇宙中的稀缺性技术
  10. 星星之火OIer:手机网络