JWT到底是个什么鬼?
前面一篇我们了解了微服务安全认证架构是如何演进而来的,但是发现v2.5架构仍然较重,有没有轻量级一点的方法呢?其实业界早已有了实践,它就是基于JWT的安全认证架构。JWT到底是个什么鬼呢?本篇为你解答!

1、V2.5版本架构存在的问题
在v2.5版本Token+Gateway模式下,适合于大部分微服务场景,但是当网站流量很大的时候,对AuthService的访问压力也会比较大,它很可能会成为性能和扩展性的瓶颈!

MyShop v2.5版本:Token+Gateway
此外,对于很多对于安全不是很敏感的微服务来说,集中状态校验就会显得很笨重。
2、V2.6版本:JWT+Gateway
在业界实践上,很多企业都在采用基于JWT令牌的无状态安全认证架构,MyShop技术团队也探索出了v2.6版本,即基于JWT+Gateway的模式:

MyShop v2.6:JWT+Gateway
v2.6在v2.5的基础之上发展而来,主要区别如下:
(1)第二步中,v2.5使用的是透明应用令牌,而v2.6使用的是JWT令牌,JWT令牌是自包含数据和签名的;
(2)第四步和第五步,v2.5需要网关每次请求都去AuthService进行校验,而v2.6网关处则不用;此处,网关就可以自行进行令牌的解析和合法性校验;解析完成后,网关就可以得到用户标识信息并向后端微服务传递了;
画外音:这里的JWT令牌有点类似于单块架构阶段v1.x版本下的无状态Session,并且针对于微服务场景进行了扩展应用。
JWT+Gateway的这种做法简化了安全认证架构,降低了AuthService的压力,总体上来说是一种高性能和可扩展的架构,适用于大部分对安全要求不太敏感的微服务应用场景。为什么说是大部分对安全要求不敏感的场景呢,这就需要我们了解一下JWT的原理了。
3、JWT的原理
JWT全程JSON Web Token,是一种用于通信双方之间传递安全信息的简洁的、URL安全的表述性声明规范,经常用在跨域身份验证。JWT最主要的特点就是它定义了一种紧凑和自包含的JSON对象格式,通过它可以在多个系统或服务之间安全的传递信息,信息经过数字签名可以校验且是可信任的。JWT主要用于 认证授权 和 信息交换 的场景,其令牌结构主要有如下图所示的3个部分组成,且不同部分之间用了一个 . 分隔:
JWT的三个组成部分
这三个组成部分分别是:Header头部、Payload消息体 以及 Signature签名。
画外音:JWT将消息体分为了Header和Payload,其实有点类似于HTTP协议,它也将请求体分为了Header和Body,Header里面一般放元数据,类似于信封上的寄件人和地址等,而Body里面则存放的是实际数据,类似于信封里面的主体内容。
下面我们来看一个JWT令牌的示例:
JWT令牌示例
我们先关注上图中的左半部分,可以看到,三个部分分别使用了不同的颜色标注了出来,并且通过 . 分隔开。
画外音:如果你没看到,那就仔细看一下!如果还没看到,那就打开放大看一下!
一般来说,我们都会通过一些工具例如jwt.io网站来查看JWT解码后的内容,也就是上图中的右半部分就是在jwt.io上进行解码后的内容。
可以看到,Header部分解码后的内容说明了这个令牌的类型是JWT,即JSON Web Token,它使用的算法是HS256算法。
然后,Payload部分解码后的内容说明了这个令牌的颁发者是谁(iss),颁发的时间(iat),令牌过期时间(exp)、这个令牌要颁发给谁(aud)以及目标用户是谁(sub)。这些信息也称为Claims,他们是官方定义的Public Claims。我们在实际使用中,也会定义一些Custom Claims,比如用户的角色信息(Role)等。
对于使用ASP.NET Core的开发童鞋,推荐阅读晓晨的这篇文章实践IdentityServer:《IdentityServer4实战-基于角色的权限控制及Claim详解》。
最后,Signature部分则表明了整个JWT的验证方式是什么样子的,即一个签名公式。如果是采用HS256算法的话,就是下面这个公式:
base64Url(Header)+"."+base64Url(Payload)+"."+base64Url(Signature)
在jwt.io上,我们可以通过输入secret进行一个令牌的合法性的校验,如果不通过则会显示Invalid Signature,通过则显示Signature Verified.

JWT令牌校验
看完了JWT的三个组成部分,及其组装公式,我们可能会发现:Header和Payload的内容是公开可见的,只要拿到Token就可以去类似jwt.io这种工具网站上进行Debug解析,那JWT真的安全吗?
画外音:JWT保证的安全可能是相对的,它不会保证传输信息的保密性,但它会保证信息的可依赖和不可篡改性(通过Signature实现)。因为Secret是保密的,所以即使一般用户拿到了你的token和算法,也无法篡改里面的数据(一旦篡改校验就会不通过)。换句话说,JWT令牌有点类似于现实世界中的签名支票,如下图所示。

签名支票
4、JWT的实现方式
上面我们了解了JWT的原理,现在来看看JWT都是如何来实现的。目前,JWT主要有两种算法实现,一种是HMAC,另一种是RSA。
HMAC流程
首先,来看看HMAC的实现流程:

HAMC流程
Step1.客户端向AuthServer发出登录请求;
Step2.AuthServer校验用户身份,通过后生成JWT数据结构且采用某种HMAC算法+Secret对JWT进行签名,最后将这个签名后的JWT令牌返回给客户端;
Step3.客户端收到JWT后一般都会做本地存储,然后在调用微服务的时候都会带上JWT令牌;
Step4.微服务接收到客户端请求和JWT令牌时,会采用同样的Secret对JWT令牌进行解析和校验,通过后则返回处理后的数据,不通过则一般返回401。
由此看来,HMAC流程中,最重要的就是secret的保密,如果泄露,则整个流程不再安全。
RSA流程
然后,来看看RSA的实现流程:

RSA流程
RSA流程总体上来说和HMAC类似,不同的是AuthServer在颁发JWT令牌的时候采用私钥Private Key进行签名,而微服务端ResourceServer在解析和校验JWT令牌的时候采用公钥Public Key进行签名。
可以看出,RSA流程比HMAC流程总体来说要安全一点,因为只有AuthServer一个地方需要保存私钥,私钥的泄露概率就小很度。其他的微服务端都使用公钥进行解签校验,但是不能够篡改加签。
画外音:其实就类似于对称加密 和 非对称加密的方式。
5、JWT学习小结
本文通过MyShop v2.5存在的问题引出了使用JWT令牌的v2.6架构,并介绍了JWT的概念、原理 和 实现方式。最后,我们来总结一下JWT的优势及不足:

我们重点关注一下JWT的不足:
(1)无状态和吊销无法两全,如果某个用户令牌异常(比如有黑客在干坏事),我们想要吊销这个用户的令牌,但是却没有办法在AuthService上进行统一吊销,一般需要等到这个JWT令牌自然过期才能吊销。又假设我们在AuthService上对某个用户的信息进行了更新,那么相关的Claims信息也必须要等到这个老的JWT过期后重新登录或刷新后产生了新的JWT后才能更新。
(2)JWT的大小会随着Claims的数量增多,也会导致JWT的大小会变大,从而也会导致传输的开销增大。最后,我们可以对有状态的透明令牌和无状态的JWT令牌做一个小结:两者各有适用场景,JWT令牌更适合于安全不敏感场景,透明令牌更适合于安全敏感场景。这里的敏感主要是指和钱、交易、支付相关的场景,以及金融、银行等业务之类的场景,这些场景可以采用集中式的有状态的透明令牌认证,其他的一般性的微服务应用场景则可以使用JWT。
画外音:对中小技术团队来说,特别是技术储备和实力都没那么强的团队,和钱相关的业务场景,宁慢三秒,不抢一秒,因为有时候想快那么一秒,可能就翻车了。

JWT到底是个什么鬼?的更多相关文章
- 被顶级学术期刊枪毙的p.Value到底是个什么鬼
总结一下,在我看来,p.Value仅仅是在,假设检验,这理论框架下,对于证据力度的一个测量.而且,我们不大可能推翻假设检验这个框架,似乎也不必要,因为,这个框架非常合理,有广泛的应用场景,有强大的生命 ...
- HTTPS到底是个什么鬼?
HTTPS随处可见,那么它到底是个什么鬼?本文我们一起来探讨一下HTTPS为什么是安全的,以及HTTPS连接建立的过程. 一.HTTPS为什么是安全的? HTTP使用明文通信,可能会被第三方窃听.篡改 ...
- Python中的logger和handler到底是个什么鬼
最近的任务经常涉及到日志的记录,特意去又学了一遍logging的记录方法.跟java一样,python的日志记录也是比较繁琐的一件事,在写一条记录之前,要写好多东西.典型的日志记录的步骤是这样的: 创 ...
- Flask中的g到底是个什么鬼?
g到底是个什么鬼? 在一次请求请求的周期,可以在g中设置值,在本次的请求周期中都可以读取或复制. 相当于是一次请求周期的全局变量. from flask import Flask,g app = Fl ...
- Google、Facebook等均开始支持的HTTP3到底是个什么鬼?
GitHub 19k Star 的Java工程师成神之路,不来了解一下吗! 最近一段时间以来,关于HTTP/3的新闻有很多,越来越多的国际大公司已经开始使用HTTP/3了. 所以,HTTP/3已经是箭 ...
- 窥探Vue.js 2.0 - Virtual DOM到底是个什么鬼?
引言 你可能听说在Vue.js 2.0已经发布,并且在其中新添加如了一些新功能.其中一个功能就是"Virtual DOM". Virtual DOM是什么 在之前,React和Em ...
- DSP到底是个什么鬼?看完你就懂了
DSP 即数字信号处理技术, DSP 芯片即指能够实现数字信号处理技术的芯片. DSP芯片是一种快速强大的微处理器,独特之处在于它能即时处理资料. DSP 芯片的内部采用程序和数据分开的哈佛结构,具有 ...
- (转)《SSO CAS单点系列》之 15分钟让你了解SSO技术到底是个什么鬼!
Web应用系统的演化总是从简单到复杂,从单功能到多功能模块再到多子系统方向发展. .当前的大中型Web互联网应用基本都是多系统组成的应用群,由多个web系统协同为用户提供服务. 多系统应用群,必然意味 ...
- Azure SQL的DTU和eDTU到底是个什么鬼
可以从上表上对应于本地数据库的性能采集的指标,可以估算出应该使用什么样级别的AZURE SQL. 当然服务层选择后仍然可以进行更改. 对于自己应用应该用多大规模的DTU,可以进行详细的评估,可以使用下 ...
随机推荐
- java NIO 原理解析之学习笔记
关键抽象 1.Buffer缓冲区 NIO数据传递模型,是一个连续的内存区域.所有数据传递均通过buffer类处理:NIO提供了字符串.整形.字节.堆等多种缓冲区. 2.Channel(通道) NIO把 ...
- Jmeter系列(39)- Jmeter 分布式测试
如果你想从头学习Jmeter,可以看看这个系列的文章哦 https://www.cnblogs.com/poloyy/category/1746599.html 为什么要做分布式 Jmeter 本身的 ...
- C# DataTable与Excel读取与导出
/// <summary> /// Excel->DataTable /// </summary> /// <param name="filePath&q ...
- python实现二维码、条形码识别
环境: python 3.7 Win7 依赖包安装: pip install pillow pip install opencv-python pip install opencv-contrib-p ...
- 使用wsl2時碰到的問題
1.啓動wsl系统时出现“参考的对象类型不支持尝试的操作”. 解决方法: netsh winsock reset
- 阿里云OSS 服务端签名后直传之分片上传(结合element-ui的upload组件)
分片上传(结合element-ui的upload组件实现自定义上传) async uploadFree(content){ let data = await this.getOssToken(); / ...
- javascript知识梳理之数据类型
javascript基础知识(在javascript中 = 是赋值符号) 变量 合法的变量命名规则:大小写英文.数字. $ 和 _ 的组合,且不能用数字开头. var a; //声明变量 var s ...
- scrapy(一):基础用法
Scrapy 框架 Scrapy 简介 Scray 是用python写的为了爬取网站数据,提取结构性数据的应用框架 Scrapy框架原理图 白话讲解Scrapy 运作流程 代码写好,程序开始运行... ...
- 数据可视化之分析篇(六)使用Power BI进行流失客户分析
https://zhuanlan.zhihu.com/p/73358029 为了提升销量,在不断吸引新客户的同时,还要防止老客户离你而去,但每一个顾客不可能永远是你的客户,不可避免的都会经历新客户.活 ...
- linux专题(三):常用的基本命令(一)目录管理
http://dwz.date/UDf 绝对路径和相对路径 我们知道Linux的目录结构为树状结构,最顶级的目录为根目录 /. 其他目录通过挂载可以将它们添加到树中,通过解除挂载可以移除它们. 在开始 ...