JWT(json web token)是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。java
JWT的声明通常被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。好比用在用户登陆上。web
在传统的用户登陆认证中,由于http是无状态的,因此都是采用session方式。用户登陆成功,服务端会保证一个session,固然会给客户端一个sessionId,客户端会把sessionId保存在cookie中,每次请求都会携带这个sessionId。算法
图片来源于网络博客json
cookie+session这种模式一般是保存在内存中,并且服务从单服务到多服务会面临的session共享问题,随着用户量的增多,开销就会越大。而JWT不是这样的,只须要服务端生成token,客户端保存这个token,每次请求携带这个token,服务端认证解析就可。服务器
图片来源于网络博客cookie
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJvcmciOiLku4rml6XlpLTmnaEiLCJuYW1lIjoiRnJlZeeggeWGnCIsImV4cCI6MTUxNDM1NjEwMywiaWF0IjoxNTE0MzU2MDQzLCJhZ2UiOiIyOCJ9.49UF72vSkj-sA4aHHiYN5eoZ9Nb4w5Vb45PsLF7x_NY网络
第一部分咱们称它为头部(header),第二部分咱们称其为载荷(payload),第三部分是签证(signature)。session
header测试
jwt的头部承载两部分信息:加密
声明类型,这里是jwt
声明加密的算法 一般直接使用 HMAC SHA256
完整的头部就像下面这样的JSON:
{
"typ": "JWT",
"alg": "HS256"
}
而后将头部进行base64加密(该加密是能够对称解密的),构成了第一部分:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
playload
载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包含三个部分
标准中注册的声明
公共的声明
私有的声明
标准中注册的声明 (建议但不强制使用) :
iss: jwt签发者
sub: jwt所面向的用户
aud: 接收jwt的一方
exp: jwt的过时时间,这个过时时间必需要大于签发时间
nbf: 定义在什么时间以前,该jwt都是不可用的.
iat: jwt的签发时间
jti: jwt的惟一身份标识,主要用来做为一次性token,从而回避重放攻击。
公共的声明 :
公共的声明能够添加任何的信息,通常添加用户的相关信息或其余业务须要的必要信息.但不建议添加敏感信息,由于该部分在客户端可解密.
私有的声明 :
私有声明是提供者和消费者所共同定义的声明,通常不建议存放敏感信息,由于base64是对称解密的,意味着该部分信息能够归类为明文信息。
定义一个payload:
{
"name":"Free码农",
"age":"28",
"org":"今日头条"
}
而后将其进行base64加密,获得Jwt的第二部分:
eyJvcmciOiLku4rml6XlpLTmnaEiLCJuYW1lIjoiRnJlZeeggeWGnCIsImV4cCI6MTUxNDM1NjEwMywiaWF0IjoxNTE0MzU2MDQzLCJhZ2UiOiIyOCJ9
signature
jwt的第三部分是一个签证信息,这个签证信息由三部分组成:
header (base64后的)
payload (base64后的)
secret (这个咱们能够使用登录用户id)
这个部分须要base64加密后的header和base64加密后的payload使用.链接组成的字符串,而后经过header中声明的加密方式进行加盐secret组合加密,而后就构成了jwt的第三部分:
49UF72vSkj-sA4aHHiYN5eoZ9Nb4w5Vb45PsLF7x_NY
密钥secret是保存在服务端的,服务端会根据这个密钥进行生成token和验证,因此须要保护好。
Maven
<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.1.0</version></dependency>
加密与校验代码:
加密方法与校验方法
测试代码:
测试方法
代码输出结果:
代码输出结果
能够很清楚的看到,第一次用生成的Token去校验,校验经过,而且输出了Token中包涵的信息。第二次用过时的Token调用校验方法,直接抛出异常,提示Token信息过时。
一、由于json的通用性,因此JWT是能够进行跨语言支持的,像JAVA,JavaScript,NodeJS,PHP等不少语言均可以使用。
二、payload部分,JWT能够在自身存储一些其余业务逻辑所必要的非敏感信息。
三、便于传输,jwt的构成很是简单,字节占用很小,因此它是很是便于传输的。它不须要在服务端保存会话信息, 因此它易于应用的扩展