概述

JSON Web Token (简称JWT)是一个开放标准(RFC 7519),它界说了一种紧凑的、自包含的方法,用于作为JSON目标在各方之间安全地传输信息。该信息可以被验证和信赖,由于它是数字签名的。

JWT首要适用场景包括:

  • 身份认证:适用较广的是在SSO场景,在客户端认证成功后,服务端签发jwt给客户端,后续客户端凭借jwt来代表自己的身份,那客户端就可以拜访一切接受这套jwt签发体系的服务端(可以跨域);当前,如果jwt被走漏,在有效期内,任何一个获得jwt的人都可以以客户端的身份和服务端合法通讯
  • 交流信息:在jwt payload中带着信息从而进行信息交流。由于jwt是有数字签名的,不可被篡改;由于payload是明文,一般在payload中不要放置灵敏信息

结构

首先JWT大概长这个姿态:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

结构上长这样xxxxx.yyyyy.zzzzz,用两个.划分为三个部分:分别是Header、Payload以及Signature。可以经过JWT官方提供的在线工具jwt.io/#debugger-i…进行在线解密插件(这也说明晰jwt的信息都是明文的 主张不要放灵敏信息)

API身份认证还得看我JWT

Header

头部信息。首要包含了JWT类型以及签名算法,签名算法有HMAC SHA256、RSA、ES等系列,引荐运用ES512

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

然后再运用Base64Url编码得到第一节信息:

$ echo -n '{"alg":"HS256","typ":"JWT"}' | base64 | tr '/+' '_-' | tr -d '='
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Payload:

声明式信息,一般叫做claims,首要由两部分构成:

  • Registered claims:官方预界说的一些字段,如iss(issuer签发者)、exp(expiration time本JWT过期时刻)、sub(subject主体信息)等
  • Private claims:使用自界说信息,在典型的SSO登录场景中,例如username、userid等信息。Payload信息是明文的,不主张放一些secret等灵敏信息

上述示例中的Payload有

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

然后再运用Base64Url编码得到第二节信息:

$ echo -n '{"sub":"1234567890","name":"John Doe","iat":1516239022}' | base64 | tr '/+' '_-' | tr -d '='
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ

Signature

签名是为了确保JWT是不可被篡改的,JWT一般由服务端的认证体系经过私钥一致签发,其他运用到JWT的体系可以经过对应的公钥进行验证,这背面的原理是根据非对称加密的签名算法,感兴趣的同学可以阅览下之前的文章/post/721633…

以HS256(HMAC+SHA256算法组合)签名算法为例,其核算逻辑如下:

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

剖析

JWT盛行的原因在于其无状况,具备去中心化的认证优势。

回想下传统的根据session+cookie的认知方法,一是有服务端横向扩展约束,一般需求引入redis来存储这些session信息;二是在触及跨域场景中会有问题,由于cookie的跨域约束。

JWT优势在于经过一致的认证中心签发JWT后,当用户带着这些JWT拜访子资源或许其他SSO内站点时,这些服务端体系可以经过JWT签名验证客户端身份,这避免了中心化的认知流程,降低了体系间的耦合度。

但是JWT也不是十分的完美,一是一旦JWT被走漏,具有JWT方就能掌握你的悉数认证信息,进行灵敏资源操作,所以一般JWT的过期时刻不宜太长;二是JWT的吊销机制比较差,一旦JWT被签发出来,由于都是根据公钥的验证机制,此刻如果管理员由于走漏危险需求吊销此JWT,单纯依靠JWT的机制是不能完成的,只能引入第三方的消息告诉机制逐个告诉到下游体系吊销该JWT,整个进程会比较繁琐。

所以主张在极点灵敏的场景下,引荐根据同享session方案完成跨域认证。实践大部分事务中,经过签发短实效性的JWT是完成可以满意安全性要求的。

使用

如果在不同后端体系间调用时需求运用JWT,其完成方案一般是每个体系维护自己的一套公私钥,并提供获取公钥方法(可以提早将公钥注册到其他体系,或许提供API以获取公钥)。

假设有A、B两体系,A需求拜访B的API,则A体系提早在B体系上注册好自己的身份,并注册公钥绑定到其身份上。恳求前,A使用私钥签发JWT,并包含身份信息,将JWT放置在header中和恳求一同发送给B。B收到后,先从JWT中获取身份信息,并使用其身份对应的公钥验证JWT,验证经过即完成了对恳求方A身份的验证

拓宽

除了JWT外,常常还能看到这些名词JWS JWE,其含义如下:

  • JWT是一种标准,其间header中制定了签名算法,当签名算法为none时,此刻的JWT也被称为非安全的JWT;反之有数据签名也被称为JWS(JWT Signature)
  • JWE(JSON Web Encryption)是一种对payload进行加密的方法(默许的JWT的payload是明文的),此刻的JWT被称为JWE

关于JWT和Oauth2的联系:

  • 首先JWT是一种token格式,Oauth2则是一种认证协议
  • JWT愈加适用于API调用的场景,用于身份认证;Oauth2适用于在浏览器、移动端、PC端等需求多端同享资源或许认证的情况下运用,Oauth2的典型场景是第三方登录(如某博客网站可以使用微信账号进行登录)