JSON Web Token (JWT)
JSON Web Token 以JSON对象的形式为信息的安全传输提供了简洁、独立的方法。是目前最流行的跨域认证解决方案。
应用场景
- 用户认证:
用户在客户端输入用户名密码后返回给服务器,服务器验证通过后生成一个JWT返回给客户端,此后每次客户端访问,都带上JWT以表明身份。目前JWT被广泛应用于单点登录。 - 信息交换:
JWT可以用于信息交换,因为JWT可以签证,通过对header和payload使用密钥签证,除了验证用户身份,还可以验证信息是否被篡改。
JWT的结构
JWT由三部分组成,三部分之间用.
分隔:
header.payload.signature
Header
Header通常包括两部分:token类型(默认JWT)、签名加密算法(如:HMAC SHA256 或 RSA)
{
"alg": "HS256",
"typ": "JWT"
}
然后使用Base64Url
将以上json内容转换为字符串,即为JWT的第一部分。
Payload
Payload(载荷)是JWT的第二部分,通常包含用户身份信息以及一些额外的信息,主要分为三部分:
- 注册声明:
iss:jwt签发者
sub:jwt面向用户
aud:接收jwt的一方
exp:jwt过期时间
iat:jwt签发时间
nbf:定义什么时间之前,该jwt是不可用的
jti:jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击
等 - 公共声明:
可以随意定义需要的额外字段,只要不跟注册声明中已定义的字段重复即可 - 私有声明:
由客户端声明,用于与服务器共享的字段
一个Payload的例子:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
同样使用Base64Url
将以上json内容转换为字符串,组成JWT的第二部分。
注意!不要将未加密的敏感数据放在Header或Payload中,因为这两部分都可以被任何人解密获取
Signature
生成Signature需要已经使用Base64Url
转换后的Header和Payload以及一个只存储在服务器的密钥:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
Signature可以用于验证Header和Payload是否被篡改。
最后,将这三部分组合起来,以.
分隔,即为一个JWT。
JWT的使用方式
客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage。
客户端每次与服务器通信,都带上这个JWT。放在Cookie中自动发送无法实现跨域,最好的做法是放在HTTP请求头的Authorization字段里:
Authorization: Bearer <token>
另一种方法,可以在跨域时将JWT放在POST数据中
JWT 特点
- JWT默认不加密,也可以在生成token后,用密钥再加密一次
- JWT不加密时不要将敏感数据写入JWT
- JWT不仅可用作认证,还可以交换信息。有效使用JWT,可降低服务器查询数据库的次数
- JWT最大的缺点是服务器不保存session状态,因此无法在使用过程中废止某个token,或更改token权限。即:一旦token签发,在有效期内始终有效,除非服务器部署额外逻辑
- JWT本身包含认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT的有效期应该设置的比较短。对一些比较重要的权限,使用时应该再次对用户进行认证(输入验证码等)
- 为减少盗用,JWT不应该用明文传输的HTTP,而用HTTPS传输
参考链接: