SpringBoot集成JWT(概念篇)

本文介绍了JWT(JSON Web Token)的概念及其组成结构,包括Header、Payload和Signature,并解释了JWT如何解决传统session和cookie方式存在的问题,如内存开销过大、分布式环境下的数据同步困难及CSRF攻击等。

1.什么是JWT呢?

        JWT 全称是JSON Web Token, 是目前最流行的跨域认证解决方案,是一种基于 Token 的认证授权机制。根据它的名字,可以知道它也是Token的一种,不过是经过大家统一规范化后的。

1.1  JWT的组成

JWT一共有三部分组成,分别是

  • Header : 描述 JWT 的元数据,定义了生成签名的算法以及 Token 的类型。

  • Payload : 用来存放实际需要传递的数据

  • Signature(签名) :服务器通过 Payload、Header 和一个密钥(Secret)使用 Header 里面指定的签名算法(默认是 HMAC SHA256)生成。

1.2 Header

Header 通常由两部分组成:

  • typ(Type):令牌类型,也就是 JWT。

  • alg(Algorithm) :签名算法,比如 HS256。

示例:

{

  "alg": "HS256","typ": "JWT"

}

 1.3 Payload

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

Claims 分为三种类型:

  • Registered Claims(注册声明) :预定义的一些声明,建议使用,但不是强制性的。

  • 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 唯一标识。

示例:

 

{

 "iss": "wx",

 "iat": 15322232,

 "sub": "1234567890",

 "name": "John Doe",

 "exp": 15323232,

 "iat": 1516239022,

 "scope": ["admin", "user"]

}

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

1.4 Signature

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

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

  • Header + Payload。

  • 存放在服务端的密钥(一定不要泄露出去)。

  • 签名算法。

签名的计算公式如下:

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

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

2.为什么要使用JWT呢?

        因为别人用所以我就用?NoNoNo,新东西的产生总是为了解决遇到的问题,具体的问题有以下几点。。。

        1.最开始,我们一般都是采用session和cookie的方式,在服务器中单独开辟一部分空间来保存session,平时进行请求时,将cookie携带到请求头中发送到后台,服务端通过这JSESSIONID判断是哪一个session,通过这样来进行登录验证。但是随着用户的不断增多,用户信息直接保存在服务端内存中,内存开销太大。
        2. 如果只有一个服务器,那么它就是单机项目, 用户信息直接保存在那个唯一的服务器中。但是当如果有多个服务器(分布式)的时候,怎么保证其它的服务器也有我存储的信息呢,所以在多台服务器无法正确拿到session信息。
        3.用户可以直接看到cookie信息, 不安全,容易受到CSRF攻击(跨站请求伪造攻击),比如可以直接通过cookie登录百度网盘,通过cookie+爬虫获取很多需要登录的网站的信息包含的信息太单一, 只有JSESSIONID。

        JWT就很好的解决了上述的三个问题。JWT 自身包含了身份验证所需要的所有信息,因此,我们的服务器不需要存储 Session 信息。这显然增加了系统的可用性和伸缩性,大大减轻了服务端的压力。而且使用 JWT 认证可以有效避免 CSRF 攻击,因为 JWT 一般是存在在 localStorage 中,使用 JWT 进行身份验证的过程中是不会涉及到 Cookie 的。

        例子:为什么要使用JWT(举例理解)

        有一家蛋糕店,在开业的时候,为了进行推广,就给来蛋糕店买蛋糕的用户,每人办了一张会员卡,通过积累消费的次数,可以换取一些小礼品。有一名用户办理了会员卡session),老板就在它小本本服务器特定空间)上记录一次。随着生意越来越好,老板决定开分店了。但是随着办理会员卡的用户越来越多了,小本本不够了。而且每次找用户的信息,还要去重新查找一遍,很麻烦,而其因为小本本只有一份,其他的分店也不能确认用户是不是会员,于是老板左思右想终于想出来了一个办法:自己设计了一款vip卡片JWT)利用老板和客户的信息组成了独一无二的vip卡片,发给用户自己保管,只要是用户本人拿着这张卡片,去到任何一个分店进行消费,都知道他是会员,而且也不怕其他人拿着vip卡片去消费。

3.JWT的工作流程

  1. 用户向服务器发送用户名、密码以及验证码用于登陆系统。

  2. 如果用户用户名、密码以及验证码校验正确的话,服务端会返回已经签名的 Token,也就是 JWT。

  3. 用户以后每次向后端发请求都在 Header 中带上这个 JWT 。

  4. 服务端检查 JWT 并从中获取用户相关信息。

4. JWT的注意事项

1.服务器的秘钥非常重要,通常我们生产环境会有一个KMS(密钥管理系统:Key Management Service,KMS)来管理秘钥,不在程序的配置文件里泄露秘钥。

2.使用安全系数高的加密算法。

3.不要将隐私信息存放在 Payload 当中。

4.Payload 要加入 exp (JWT 的过期时间),永久有效的 JWT 不合理。并且,JWT 的过期时间不易过长。

SpringBoot具体集成JWT,看下一篇

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值