Skip to main content

Json Web Token介绍

分类:  Asp.net Core认证和授权 标签:  #Asp.Net core基础 #认证 #.Net 发布于: 2023-05-27 18:53:17

今天来学一下关于认证的理论基础。

先想一个问题:我们以前是怎么做认证的呢?

以前最简单的办法是基于Session的方式,所谓的Session的方式是系统向用户展示一个登录的界面,用户提供正确的依据(例如用户密码)在登录处登录成功后(SignIn), Web系统针对这一次生成一个唯一的ID,同时服务器侧生成和用户相关的信息,例如一个用户对象,这个用户对象里可能保存各种和用户相关的信息,例如用户的ID, 用户的电话等等信息,这部分信息系列化之后存放在服务器侧,然后将生成的唯一ID存于cookie或者是URL查询字符串的形式返回给客户端,用户端每次需要访问资源的时候会这个唯一的ID以cookie或者是以为header值或者是URL查询字符串等形式带入到服务器侧,服务器根据ID 再次从服务器侧查询到和ID相关的用户信息,需要的时候反序列化出来就可以了。

这个方案在之前是可以达成的,但是后期随着互联网应用的爆炸式增长,类似这样的设计很容易形成瓶颈,例如PHP中,所有的Session数据默认放入临时文件目录中,ASP.net 初期放在内存中等等,这个时候如果Web 服务器需要放置在负载均衡后面的时候,这个时候需要将所有的Session数据放置于共享的存储中,例如放在Redis这样的分布式缓存中,或者放置在书库中等等,但是这种设计在大流量的时候容易使得存储用户数据的中心成为唯一的故障点。

同时随着后期的应用的发展,同一个应用可能有多种客户端,例如另外一个网站,另外一个API, 或者是手机客户端,或者是单页应用(SPA),  这就是随着后来的发展到使用token进行认证。

Token的认证形式主要是在于起初使用Session将用户的信息存储在服务端,改成使用token存放在客户端,同样取得了Token之后,需要在每次访问的时候要将Token 带入到访问请求中,这个大家已经很熟悉了,例如使用Json Web token 在访问的请求头中传递,达到认证的目的。


虽然我们想到了使用token来解决认证的问题,但是token明显有几个问题:

  1. 生成了token之后,由于token是保存在客户端,服务器端是如何知道客户端有没有伪造token?

  2. 生成了token之后,我们将用户的一些信息放入token中后,服务器端的用户信息假如改变了,token该如何反应这种改变呢?

这里我就需要学习一下JsonWeb Token的基础理论了。

Jason Web Token 一共有三个部分,三个部分分别以.进行链接,具体的格式如下:
{HEADER}.{PLAYLOAD}.{Signature}

 需要注意的是,由于JsonWeb token的内容是以文本的形式传递的,所有通讯的协议肯定是需要采用HTTPS的,保证客户端和服务器端的通讯不会被监听。

 我们现在详细的解说一下Jason web token的结构

第一部分是{Header}, 这部分的内容基本是固定的,主要是放置JWT的元数据,是一个json对象,例如:
{
"alg": "HS256",
"type": "JWT",
 
}
 

这里alg的意思是三个部分中用于签名的加密算法,默认是HMAC SHA256, 简写为: HS256, 对于Json web token, type就是JWT,

 

这个部分的内容使用base64URL编码之后,形成一个字符串。作为Json Web Token中的三个部分的header.

 

然后关于第二个部分,Playload,实际上就我们在Session服务器端存放的用户的相关信息,当然对于Json Web Token应用到不同的方案中有一些硬性的规定,例如Qauth2.0和OpenIdConnect 这样的协议会规定某些信息必须有。同时需要注意的是这个部分是以键值对来呈现的。

JWT 规定了如下7个字段可以使用:

  • iss (issuer):签发人

  • exp (expiration     time):过期时间

  • sub (subject):主题

  • aud (audience):受众

  • nbf (Not     Before):生效时间

  • iat (Issued     At):签发时间

  • jti (JWT ID):编号

 

其他的当Json WebToken用于其他的方案,其他的方案也会加入一些JWT中没有的字段或者规则

 

定义好Playload这个部分之后,也会以base64URL进行编码。然后作为token中的第二个部分。

 

然后我们刚刚讨论过一般jsonweb token以非加密的形式在应用之间传播,那么我们为了确保该token不给篡改,那么我们还有一个部分就是签名部分,这个签名的部分是在服务器端使用保存在服务器端的一个密码,对于header+ playload这个两个部分进行加密签名,所以在服务器端的这个密码是被严密的保护起来,加密并签名传递给客户端之后,客户端无法伪造该token, 这也保证了该token的安全性。

 

虽然Json web token对我们目前的多种类型的应用有很大的帮助,但是json token的认证形式还是有一些问题的:

  1. Json web token默认是不加密的,所以不要将私密信息写入token

  2. Json web token一点被签发在有效期内,任何应用拿到之后都可以直接访问,所以对于json web token要做好保密工作,HTTPS是必须的。

  3. 同样由于Json web token 在签发有效期内,假如放入了自定义的信息,自定义在服务器端改变,json web     token有效期内并不能感知这个变化,需要定义逻辑应对这种情况。

  4. Jason web Token 本身包含了不少信息,对于这些信息要慎重,同时签发的过期时间不宜过长。