JWT-jwt是什么

一、JWT简介

1、什么是jwt

JWT(JSON WEB TOKEN):JSON网络令牌,JWT是一个轻便的安全跨平台传输格式,定义了一个紧凑的自包含的方式在不同实体之间安全传输信息(JSON格式)。它是在Web环境下两个实体之间传输数据的一项标准。实际上传输的就是一个字符串。广义上讲JWT是一个标准的名称;狭义上JWT指的就是用来传递的那个token字符串。
 

2、jwt可以做什么

由于http协议是无状态的,所以客户端每次访问都是新的请求。这样每次请求都需要验证身份,传统方式是用session+cookie来记录/传输用户信息,而JWT就是更安全方便的方式。它的特点就是简洁,紧凑和自包含,而且不占空间,传输速度快,而且有利于多端分离,接口的交互等等。
JWT是一种Token规范,主要面向的还是登录、验证和授权方向,当然也可以用只来传递信息。一般都是存在header里,也可以存在cookie里。
 

3、jwt使用场景

  • Authorization (授权) : 这是使用JWT的最常见场景。一旦用户登录,后续每个请求都将包含JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是现在广泛使用的JWT的一个特性,因为它的开销很小,并且可以轻松地跨域使用(有点像通关文牒)。
  • Information Exchange (信息交换) : 对于安全的在各方之间传输信息而言,JSON Web Tokens无疑是一种很好的方式。因为JWT可以被签名,例如,用公钥/私钥对,你可以确定发送人就是它们所说的那个人。另外,由于签名是使用头和有效负载计算的,您还可以验证内容没有被篡改。
  • 其他
 

二、JWT组成

1、初识jwt

a、这是一个标准的jwt密文字符串,一般在项目中传输的就是这种格式的jwt。
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.
eyJhdWQiOiIzN2Q4NWI0ZS0wN2EwLTRhNjctOTMyNi1jMjE3N2M0YWM1MDgiLCJwaG9uZSI6IjEyMzQ1Njc4OTAiLCJleHAiOjE2MjkxOTE4NzksImlhdCI6MTYyOTE5MTg0OX0.
It3uim-1pwsZtKfpnXLqvo5nEjwyytPXiiyc6vJ12s8

 b、这是一个明文状态的jwt字符串。

{"alg":"HS256","typ":"JWT"}.
{"aud":"37d85b4e-07a0-4a67-9326-c2177c4ac508","phone":"1234567890","exp":1629191879,"iat":1629191849}.
{秘钥}

2、JWT可以分为三个部分:

  • header(头部)
  • payload(载荷)
  • signature(签证)

 JWT官网:JWT官方网站

三、JWT解析

1、jwt的头部(header)

jwt的头部承载两部分信息:
  • 声明类型,这里是jwt
  • 声明加密的算法 ,通常直接使用 HMAC SHA256
完整的头部就像下面这样的JSON:
{"alg":"HS256","typ":"JWT"}
然后将头部进行base64加密(该加密是可以对称解密的),构成了第一部分.
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
 jwt的头部除了默认有alg与typ字段外,也是可以添加自定义信息的,添加方式:
JWT.create().withHeader(map)

 map中存放自定义信息就可以。

注意:自定义字段名不能是alg与typ,设置了也不会生效。

 

2、jwt的载荷(payload)

payload用来承载要传递的数据,它的json结构实际上是对JWT要传递的数据的声明,这些声明被JWT标准称为claims(声明),它的每个属性键值对其实就是一个claim(声明)。
JWT有三种声明:
  • Reserved claims(标准声明)
  • Private claims(私有声明)
  • public claims(公共声明)

 

a、标准声明:
JWT规定的标准声明 (建议但不强制使用)。
  • iss(Issuser):代表这个JWT的签发主体;
  • sub(Subject):代表这个JWT的主体,即它的所有人;
  • aud(Audience):代表这个JWT的接收对象;
  • exp(Expiration time):是一个时间戳,代表这个JWT的过期时间;
  • nbf(Not Before):是一个时间戳,代表这个JWT生效的开始时间,意味着在这个时间之前验证JWT是会失败的;
  • iat(Issued at):是一个时间戳,代表这个JWT的签发时间;
  • jti(JWT ID):是JWT的唯一标识,主要用来作为一次性token,从而回避重放攻击。

 

b、私有声明:
私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。
 
c、公共声明:
公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密。
 
定义一个payload:
{"aud":"37d85b4e-07a0-4a67-9326-c2177c4ac508","phone":"1234567890","exp":1629191879,"iat":1629191849}
然后将其进行base64加密,得到JWT的第二部分:
eyJhdWQiOiIzN2Q4NWI0ZS0wN2EwLTRhNjctOTMyNi1jMjE3N2M0YWM1MDgiLCJwaG9uZSI6IjEyMzQ1Njc4OTAiLCJleHAiOjE2MjkxOTE4NzksImlhdCI6MTYyOTE5MTg0OX0
 

3、jwt的签证(signature)

这个签证信息由三部分组成:
  • header (base64后的)
  • payload (base64后的)
  • secret
这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,加上secret后的组合字符串,再通过header中声明的加密方式进行加密,然后就构成了jwt的第三部分。
secret = '秘钥'
encodedString = base64(header) + '.' + base64(payload)
signature = HMACSHA256(encodedString, secret)
 
jwt = base64(header) + '.' + base64(payload) + '.' + signature
secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。
 
 

posted @ 2021-08-19 13:08  砰砰的猿  阅读(396)  评论(0编辑  收藏  举报