什么是JWT

JWT官网

JSON Web Token(JWT)是一个开放标准(RFC 7519),该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

JWT 的数据结构

例子:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wva3VrdS5odXNhbzcwMzE1LCJkYXRhIjp7InVpZCI6MX19.PyUbtFEzDTq1i_SXgD-ArNJrjym9PLXK5d7ghJK9FUI

JWT通常由三部分组成: 头部(Header), 载荷(Payload)和签名(Signature)。其三段信息用 . 连接组成JWT字符串。

Header 部分是一个 JSON 对象,承载着两部分信息;将其进些base64加密(运用对称加密)即可构成JWT的第一部分。

1
2
3
4
{
'typ': 'JWT', typ属性表示这个令牌(token)的类型(type),JWT 令牌统一写为JWT
'alg': 'HS256' //alg属性表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256)
}

Payload

Payload 用来存放需传递信息的地方,其部分是一个包含 claims 的 JSON 对象,其中claims有三种类型: registered claims(标准注册声明), public claims(公共声明), and private claims(私有声明)。

标准注册声明 常用属性如下(非强制使用), 全部属性;

  • iss: 签发者
  • sub: jwt所面向的用户
  • aud: 接收jwt的一方
  • exp: 到期时间(必须要大于签发时间)
  • nbf: 定义在什么时间之前,该jwt都是不可用的
  • iat: 签发时间
  • jti: jwt唯一ID标识

公开声明:使用JWT的人员可以随意定义这些声明。但是为避免冲突,应在IANA JSON Web令牌注册表中定义它们,或将其定义为包含抗冲突名称空间的URI。

私人权利:这些都是使用它们同意并既不是当事人之间建立共享信息的自定义声明注册或公众的权利要求。

有效载荷示例如下:

1
2
3
4
5
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}

然后将其进行base64加密,得到Jwt的第二部分。

Signature

Signature 部分是对上面两部分数据签名,通过指定的算法生成哈希,以确保数据不会被篡改。

注意:若使用标头中指定的签名算法(默认情况下为HMAC SHA256),需指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。

JWT 的特点和注意事项

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