JWT初了解

1. 概述

jwt全称 Json Web Token,强行翻译过来就是json格式的互联网令牌,本质就是, 把用户信息通过加密后生成的一个字符串。
它要解决的问题,就是为多种终端设备提供统一的、安全的令牌格式。
在这里插入图片描述

2. JWT的组成

为了保证令牌的安全性,jwt令牌由三部分组成,分别是:

  1. header:令牌头部,记录了整个令牌的类型和签名算法
  2. payload:令牌负荷,记录了保存的主体信息,比如你要保存的用户信息就可以放到这里
  3. signature:令牌签名,按照头部固定的签名算法,对整个令牌进行签名,该签名的作用是:保证令牌不被伪造和篡改
    它们组合而成的完整格式是:header.payload.signature,例如:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.
eyJzdWIiOiJ7XCJjdXJyZW50VXNlcklkXCI6MjQ4NjMwNDAwNTk0NzgwMTYsXCJjdXJyZW50UGhvbmVOdW1iZXJcIjpcIjE4OTYzNTgwMzk1XCIsXCJjdXJyZW50SWRlbnRpdHlJZFwiOjI0ODYzMDQwMzI3OTEzNDcyfSIsImlzcyI6IkpJVUpJVV9DVCIsImN1cnJlbnRVc2VySWQiOjI0ODYzMDQwMDU5NDc4MDE2LCJjdXJyZW50UGhvbmVOdW1iZXIiOiIxODk2MzU4MDM5NSIsImN1cnJlbnRJZGVudGl0eUlkIjoyNDg2MzA0MDMyNzkxMzQ3MiwiaWF0IjoxNjgzMjcxODcwLCJleHAiOjE3MTQ4MDc4NzB9.
gXhxShwXnK81InnObEhr5MWyaTnTCKWwMgXTyh2XB6k

在此故意在“.”后面进行分行

2.1 header

它是令牌头部,记录了整个令牌的类型和签名算法
它的格式是一个json对象,如下:

{
  "alg":"HS256",
  "typ":"JWT"
}
  • alg:signature部分使用的签名算法,通常可以取两个值
    1.HS256:一种对称加密算法,使用同一个秘钥对signature加密解密
    2.RS256:一种非对称加密算法,使用私钥加密,公钥解密
  • type:整个令牌的类型,固定写JWT即可
    设置好了header之后,就可以生成header部分了,具体生成方法就是把header部分使用base64 url编码即可

base64 url 不是一个加密算法,而是一种编码方式,它是在base64 算法的基础上对+=/三个字符做出特殊处理的算法;
base64 是使用64个可打印字符来表示一个二进制数据

2.2 payload

这部分是jwt的主体信息,它仍然是一个JSON对象,它可以包含以下内容:

{
  	"ss""发行者",
	"iat""发布时间",
	"exp""到期时间",
	"sub""主题",
	"aud""听众",
	"nbf""在此之前不可用",
  	"jti""JWT ID"
}

以上属性可以全写,也可以一个不写,它只是一个规范,就算写了,也需要我们在将来验证这个jwt令牌时手动处理才能发挥作用。

上述属性表达的含义分别是:

  • ss:发行该jwt的是谁,可以写公司名字,也可以写服务名称
  • iat:该jwt的发放时间,通常写当前时间的时间戳
  • exp:该jwt的到期时间,通常写时间戳
  • sub:该jwt用于干嘛的
  • aud:该jwt是发放给哪个终端的,可以是终端类型,也可以是用户名称,随意一点
  • nbf:一个时间点,在该时间点到达之前,这个令牌是不可用的
  • jti:jwt的唯一编号,设置此项的目的,主要是为了防止重放攻击(用户使用之前的令牌发送到服务器,被服务器正确的识别,从而导致不可预期的行为发生)

除此之外,我们可以加入任意的自定义信息,当用户登陆成功之后,我们可能需要把用户的一些信息写入到jwt令牌中,比如用户id、账号等等

2.3 signature

这一部分是jwt的签名,正是它的存在,保证了整个jwt不被篡改。

这部分的生成,是对前面两个部分的编码结果,按照header部分指定的方式进行加密,当然我们需要指定一个秘钥。
即:签名=HMACSHA256(base64UrlEncode(header)+“.”+base64UrlEncode(payload),secret)

由于签名使用的秘钥保存在服务器,这样一来,客户端就无法伪造出签名,因为它拿不到秘钥。换句话说,之所以无法伪造jwt,就是因为第三部分的存在。

而前面两部分并没有加密,只是一个编码结果而已,可以认为几乎是明文传输

这不会造成太大的问题,因为,既然用户登录成功了,它当然有权利查看自己的用户信息,
甚至在某些网站,用户的基本信息可以被任何人查看
我们要保证的是,不要把敏感的信息存放到jwt中,比如密码、身份证号等

jwt的signature可以保证令牌不被伪造,那如何保证令牌不被篡改呢?
比如,某个用户登陆成功了,获得了服务器返回的jwt,但他人为的篡改了 payload,比如把自己的账户余额修改为原来的两倍,然后重新编码出 payload 发送到服务器,服务器如何得知这些信息被篡改过了呢?

这就说到令牌的验证了

3. 令牌的验证

在这里插入图片描述
令牌在服务器组装完毕后,会以任意的方式发送到客户端

客户端会把令牌保存起来,后续的请求会将令牌发送给服务器

而服务器需要验证令牌是否正确,如何验证呢?
就是对 header+payload 用同样的秘钥和加密算法进行重新加密,然后把加密的结果和传入jwt的 signature 进行对比,如果完全相同,则表示前面两部分没有动过,就是自己颁发的,如果不同,肯定是被篡改过了。

当令牌验证为没有被篡改后,服务器可以进行其他验证:比如是否过期、听众是否满足要求等等,这些就视情况而定了

注意:这些验证都需要服务器手动完成,没有哪个服务器会给我们进行自动验证,当然,我们可以借助第三方库完成这些操作

4. 总结

  • jwt本质上是一种令牌格式。它和终端设备无关,它只是规范了令牌的格式而已
  • jwt由三部分组成:header、payload和signature。主体信息在payload
  • jwt难以被篡改和伪造。这是因为有第三部分的签名存在

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值