Json web token(JWT)是为了网络应用环境间传递声明而执行的一种基于JSON的开发标准(RFC 7519),该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明通常被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也能够增长一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。git
咱们知道http协议是无状态的,一般咱们为了进行用户认证,流程大概以下:github
1.客户端发送用户名和密码给服务器;
2.服务器接验证经过后,会将当前会话(session)中保存用户信息;
3.服务器向客户端发送一个session_id做为会话凭证,并写入cookie;
4.用户每次请求从cookie中获取session_id并发送给服务器;
5.服务器验证session_id,web
session认证的缺点:算法
难以拓展 用户认证以后,服务端作认证记录,若是认证的记录被保存在内存的话,这意味着用户下次请求还必需要请求在这台服务器上,这样才能拿到受权的资源,这样在分布式的应用上,响应的限制了负载均衡器的能力,也意味着限制了应用的扩展性。json
CSRF 由于是基于cookie来进行用户识别的,cookie若是被截获,用户就会很容易受到跨站请求伪造的攻击。api
基于token的鉴权机制相似于http协议也是无状态的,它不须要在服务端去保留用户的认证信息或会话信息。这也就意味着机遇tokent认证机制的应用不须要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利。安全
这个token必需要在每次请求时发送给服务器,它应该保存在请求头中,另外,服务器要支持CORS(跨来源资源共享)策略,通常咱们在服务端这么作就能够了 Access-Control-Allow-Origin:*bash
JWT是由三部分构成,将这三段信息文本用连接构成了JWT字符串。就像这样服务器
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.
eyJVc2VySWQiOjEyMywiVXNlck5hbWUiOiJhZG1pbiJ9.
Qjw1epD5P6p4Yy2yju3-fkq28PddznqRj3ESfALQy_U
复制代码
第一部分咱们称它为头部(header)第二部分咱们称其为载荷(payload,相似于飞机上承载的物品),第三部分是签证(signature)cookie
Header
JWT的头部承载的两部分信息:
{
'typ':'JWT',
'alg':'HS256'
}
复制代码
而后将头部进行base64加密(该加密是能够对称解密的),构成了第一部分
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
复制代码
plyload
Payload 部分也是一个 JSON 对象,用来存放实际须要传递的数据。JWT 规定了7个官方字段,供选用。
Signature
Signature 部分是对前两部分的签名,防止数据篡改。
首先,须要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。而后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
复制代码
注意:secret是保存在服务器端的,jwt的签发也是在服务端的,secret就是用来进行jwt的签发和jwt的验证,因此它就是你服务端的私钥,在任何场景都不该该流露出去,一旦客户端得知这个secret,那就意味着客户端能够自我签发jwt了
通常是在请求头里加入Authorization,并加上Bearer标注:
fetch('api/user/1', {
headers: {
'Authorization': 'Bearer ' + token
}
})
复制代码