【博客366】JWT(JSON Web Token)

内容: 记录JWT(JSON Web Token)

JWT概念:

JWT是什么?
JSON Web Token (JWT),它是目前最流行的跨域身份验证解决方案

JWT最大的特点:

为什么使用JWT?
JWT的精髓在于:“去中心化”,数据是保存在客户端的

JWY原理简述:

JWT的工作原理:

1. 是在服务器身份验证之后,将生成一个JSON对象并将其发送回用户,示例如下:
{"UserName": "xiaoming","Role": "User","Expire": "2020-08-08 20:00:00"}

2. 之后,当用户与服务器通信时,客户在请求中发回JSON对象

3. 为了防止用户篡改数据,服务器将在生成对象时添加签名,并对发回的数据进行验证

JWT的组成:

一个JWT实际上就是一个字符串,它由三部分组成:
头部(Header)
载荷(Payload)
签名(signature)

注意:
它是一个很长的字符串,中间用点(.)分隔成三个部分。注意,JWT 内部是没有换行的

比如:Header.Payload.Signature

JWT组成成分规则:

Header(头部){"typ":"JWT","alg":"HS256"}

typ属性:用来标识整个token字符串是一个JWT字符串;
alg属性:用来说明这个JWT签发的时候所使用的签名和摘要算法

typ跟alg属性的全称是type跟algorithm,分别是类型跟算法的意思。


Payload(负荷){"sub":"123","name":"Tom","admin":true}

payload用来承载要传递的数据,它的json结构实际上是对JWT要传递的数据的一组声明,
这些声明被JWT标准称为claims

它的一个“属性值对”其实就是一个claim;
每一个claim的都代表特定的含义和作用。

如上面结构中:
sub代表这个token的所有人,存储的是所有人的ID;
name表示这个所有人的名字;
admin表示所有人是否管理员的角色。

当后面对JWT进行验证的时候,这些claim都能发挥特定的作用

根据JWT的标准,这些claims可以分为以下三种类型:

A. Reserved claims(保留)
它的含义就像是编程语言的保留字一样,属于JWT标准里面规定的一些claim。
JWT标准里面定义好的claim有:
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的唯一标识。

B. Public claims(共有)

C. Private claims(私有)
这个指的就是自定义的claim,比如前面那个示例中的admin和name都属于自定的claim。

这些claim跟JWT标准规定的claim区别在于:
JWT规定的claim,JWT的接收方在拿到JWT之后,都知道怎么对这些标准的claim进行验证;
而private claims不会验证,除非明确告诉接收方要对这些claim进行验证以及规则才行

signature(签名)
签名是把header和payload对应的json结构进行base64url编码之后得到的两个串用英文句
点号拼接起来,然后根据header里面alg指定的签名算法生成出来的。

算法不同,签名结果不同。以alg: HS256为例来说明前面的签名如何来得到。

按照前面alg可用值的说明,HS256其实包含的是两种算法:HMAC算法和SHA256算法,
前者用于生成摘要,后者用于对摘要进行数字签名。这两个算法也可以用HMACSHA256来统称

JWT的验证:

它验证的方法其实很简单,只要把header做base64url解码,就能知道JWT用的什么算法做的签名,
然后用这个算法,再次用同样的逻辑对header和payload做一次签名,并比较这个签名是否与JWT
本身包含的第三个部分的串是否完全相同,只要不同,就可以认为这个JWT是一个被篡改过的串,
自然就属于验证失败了。

接收方生成签名的时候必须使用跟JWT发送方相同的密钥!!!!

在验证一个JWT的时候,签名认证是每个实现库都会自动做的,但是payload的认证是由使用者来
决定的。因为JWT里面可能会包含一个自定义claim,所以它不会自动去验证这些claim

JWT的签名(上面三个组成成分的signature):

Signature 部分是对前两部分的签名,防止数据篡改。

首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。
然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。

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

算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间
用"点".)分隔,就可以返回给用户。

base64url与base64:

Base64URL:
前面提到,Header 和 Payload 串型化的算法是 Base64URL。这个算法跟Base64算法
基本类似,但有一些小的不同。

JWT 作为一个令牌(token),有些场合可能会放到 URL:
(比如 api.example.com/?token=xxx)。

 Base64 有三个字符+/=,在 URL 里面有特殊含义,所以要被替换掉:
 =被省略、+替换成-/替换成_ 。

这就是 Base64URL 算法!

JWT特点:

1、JWT 默认是不加密,但也是可以加密的。生成原始 Token 以后,可以用密钥再加密一次。
 2、JWT 不加密的情况下,不能将私密数据写入 JWT。
 3、JWT 不仅可以用于认证,也可以用于交换信息。
    有效使用 JWT,可以降低服务器查询数据库的次数。
 4、JWT 的最大缺点是,由于服务器不保存 session 状态,无法在使用过程中废止某个token,
    或更改 token 的权限。也就是说,一旦JWT签发了,在到期之前就会始终有效,除非服务器
    部署额外的逻辑。
 5、JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,
    JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。
 6、为了减少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用 HTTPS 协议传输。

JWT与Session:

 JWT与Session的差异
 1、相同点是,它们都是存储用户信息;然而,Session是在服务器端的,而JWT是在客户端的。
 
 2、Session方式存储用户信息的最大问题在于要占用大量服务器内存,增加服务器的开销。
 
 3、而JWT方式将用户状态分散到了客户端中,可以明显减轻服务端的内存压力。
 
 4、Session的状态是存储在服务器端,客户端只有session id;而Token的状态是存储在客户端。

token相比cookie的优点:

使用Token的优点:
 1、无状态和可扩展性:Tokens存储在客户端。完全无状态,可扩展。我们的负载均衡器可以将
    用户传递到任意服务器,因为在任何地方都没有状态或会话信息。
    
 2、安全:Token不是Cookie。(The token, not a cookie.)每次请求的时候Token都会
 被发送。而且,由于没有Cookie被发送,还有助于防止CSRF攻击。即使在你的实现中将token
 存储到客户端的Cookie中,这个Cookie也只是一种存储机制,而非身份认证机制。没有基于
 会话的信息可以操作,因为我们没有会话。
 
 3、token在一段时间以后会过期,这个时候用户需要重新登录。这有助于我们保持安全。还有
 一个概念叫token撤销,它允许我们根据相同的授权许可使特定的token甚至一组token无效。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值