JSON Web Token(JWT)

什么是JWT

Json web token(JWT)是为了网络应用环境间传递声明而执行的一种基于JSON的开发标准(RFC 7519),该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明通常被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也能够增长一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。git

为何用JWT

咱们知道http协议是无状态的,一般咱们为了进行用户认证,流程大概以下:github

1.客户端发送用户名和密码给服务器;
2.服务器接验证经过后,会将当前会话(session)中保存用户信息;
3.服务器向客户端发送一个session_id做为会话凭证,并写入cookie;
4.用户每次请求从cookie中获取session_id并发送给服务器;
5.服务器验证session_id,web

session认证的缺点:算法

  • 难以拓展 用户认证以后,服务端作认证记录,若是认证的记录被保存在内存的话,这意味着用户下次请求还必需要请求在这台服务器上,这样才能拿到受权的资源,这样在分布式的应用上,响应的限制了负载均衡器的能力,也意味着限制了应用的扩展性。json

  • CSRF 由于是基于cookie来进行用户识别的,cookie若是被截获,用户就会很容易受到跨站请求伪造的攻击。api

JWT原理

基于token的鉴权机制相似于http协议也是无状态的,它不须要在服务端去保留用户的认证信息或会话信息。这也就意味着机遇tokent认证机制的应用不须要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利。安全

  • 用户使用帐户和密码请求服务器;
  • 服务器验证用户信息;
  • 服务器验证经过后返回惟一token给客户端;
  • 客户端保存token,并每次请求带上;
  • 服务器验证token,并返回数据;

这个token必需要在每次请求时发送给服务器,它应该保存在请求头中,另外,服务器要支持CORS(跨来源资源共享)策略,通常咱们在服务端这么作就能够了 Access-Control-Allow-Origin:*bash

JWT的构成

JWT是由三部分构成,将这三段信息文本用连接构成了JWT字符串。就像这样服务器

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.
eyJVc2VySWQiOjEyMywiVXNlck5hbWUiOiJhZG1pbiJ9.
Qjw1epD5P6p4Yy2yju3-fkq28PddznqRj3ESfALQy_U
复制代码

第一部分咱们称它为头部(header)第二部分咱们称其为载荷(payload,相似于飞机上承载的物品),第三部分是签证(signature)cookie

Header

JWT的头部承载的两部分信息:

  • 声明类型,这里是jwt
  • 声明加密的算法,一般直接使用HMAC SHA256
{
 'typ':'JWT',
 'alg':'HS256'  
}
复制代码

而后将头部进行base64加密(该加密是能够对称解密的),构成了第一部分

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
复制代码

plyload

Payload 部分也是一个 JSON 对象,用来存放实际须要传递的数据。JWT 规定了7个官方字段,供选用。

  • iss (issuer):签发人
  • exp (expiration time):过时时间
  • sub (subject):主题
  • aud (audience):受众
  • nbf (Not Before):生效时间
  • iat (Issued At):签发时间
  • jti (JWT ID):编号

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
    }
  })
复制代码

总结

  • 由于json的通用性,因此JWT是能够跨语言支持的,像C#,JavaScript,NodeJS,PHP等许多语言均可以使用
  • 由于由了payload部分,因此JWT能够在自身存储一些其它业务逻辑所必要的非敏感信息
  • 便于传输,jwt的构成很是简单,字节占用很小,因此它是很是便于传输的
  • 它不须要在服务端保存会话信息,因此它易于应用的扩展
  • 不该该在jwt的payload部分存储敏感信息,由于该部分是客户端可解密的部分
  • 保护好secret私钥。该私钥很是重要
  • 若是能够,请使用https协议

转载地址: github.com/huzhao0316/…
相关文章
相关标签/搜索