JWT(JSON Web Token)是比较流行的跨域认证解决方案。
一般来说做单点登录见常的方式是将登录凭证持久化,各服务都向持久层请求数据,这样内部多个应用系统就可以共享登录状态。另一种方式是服务端只生成相关凭证但不保存,客户端先请求生成凭证,然后每次请求时将这个凭证带上,由服务端校验这个凭证是否有效。JWT就是这种方案

JWT原理

JWT原理是,服务器认证以后,生成一个JSON对象,返给用户

{
    "姓名":"张三",
     "角色":"管理员",
    "到期时间":"2018/7/1 12:30"
}

以后用户与服务端通信时,都要带上这个数据(该会进行加密处理)服务端对这个数据进行校验来判断这个数据的有效性。

以下是JWT认证方式的一个简图
image.png

JWT的数据结构

实际的JWT类似下面的数据:

eyJhbGciOiJIUzI1NiJ9.eyJ2YWx1ZSI6eyJuYW1lIjoiIiwidXNlcklkIjoiNTkxMTciLCJhdmF0YXJVcmwiOiIifSwiZWZmIjoxNzE5NDgyMTg0NTY5fQ.tE5PntqYNJOs0LPWM-aslmL4XAgXdADMgwuJy7-qPk8

它是一个很长的字符中,中间使用.分隔成三部分,三部分内容依次如下:

  • Header(头部)
  • Payload(负载)
  • Signature(签名)

Header部分

Header部分是一个JSON对象,描述JWT的元数据,示例:

{
  "alg":"HS256",
  "typ":"JWT"
}

alt属性表示签名的算法(algorithm),默认是HMAC SHA256;typ属性表示这个令牌的类型,最后将上面的JSON对象使用Base64URL算法转成字符串。

Payload

Payload部分也是一个JSON对象,用来存放实际需要传递的数据。JWT的7个官方字段:

iss(issuer):签发人
exp(expiration time):过期时间
sub(subject):主题
aud(audience):受众
nbf(Not Before):生效时间
iat(Issued At):签发时间
jti(JWT ID):编号

除了上面的官方字段外,我们在这个部分还可以定义私有字段:

{
  "sub":"123",
  "name":"John Doe",
  "admin":true
}

需要注意的是,JWT默认是不加密的,任何人都有可能读取到,所以不要将秘密信息放在这个部分。
这个JSON对象也要使用Base64URL算法转成字符串

Signature

Signature部分是对前两部分的签名,防止数据篡改
首先,需要指定一个密钥,这个密钥只有服务器才知道,不能泄露给用户,然后,使用Header里指定的签名算法(默认是HMAC SHA256)按照下面的公司生产签名:

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

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

JWT的使用方式

客户端收到服务器返回的JWT,可以储存在Cookie里面,也可以储存在localStorage,此后,客户端每次与服务器通信,都要带上这个JWT。

JWT的几个特点

  • JWT不存储任何数据,可使服务器免除session存取的压力,同时在集群机或多子站上面,也免除了session需要同步的烦恼。
  • JWT默认是不加密的,但也可以在生成Token以后,再使用密钥加密一次
  • JWT的缺点是,由于服务端不保存session状态,因此无法在使用过程中废止某个token,或者更改token的权限,也就是说,一旦JWT签发了,在到期之前就会始终有效,除非服务端部署额外逻辑
  • JWT本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限,所以JWT的有效期应该设置得比较短
  • 为了安全,JWT不建议使用HTTP协议明码传输,要使用HTTPS传输

还参考了:JWT(JSON Web Token) 原理简析


步履不停
38 声望12 粉丝

好走的都是下坡路


« 上一篇
Netty学习三
下一篇 »
ES DSL学习