Json web token 详解(一)

来源:互联网 发布:vb.net dock 顺序 编辑:程序博客网 时间:2024/05/17 20:28

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


如下所示一个加密后jwt信息:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
是由.分割的三部分组成,分别为Header、Payload、Signature。

一个JWT实际上就是一个字符串,它由三部分组成,Header(头部)、Payload(载荷)与Signature(签名)。


header
头部用于描述关于该JWT的两部分信息:

  •  typ 声明类型,这里固定是JWT
  •  alg 声明加密的算法 ,可选值为HS256、RSA等
完整的头部就像下面这样的JSON:

{  "typ": "JWT",  "alg": "HS256"}
然后将头部进行base64加密(该加密是可以对称解密的),构成了第一部分

eyJ0eXBlIjoiSldUIiwiYWxnIjoiSFMyNTYifQ


Payload
载荷是指签名信息以及内容,大致分为标准中注册的声明;公共的声明;私有的声明,详细介绍请参考官网。

标准中注册的声明 (建议但不强制使用) :

  • iss: jwt签发者
  • sub: jwt所面向的用户
  • aud: 接收jwt的一方
  • exp: jwt的过期时间,这个过期时间必须要大于签发时间
  • nbf: 定义在什么时间之前,该jwt都是不可用的.
  • iat: jwt的签发时间
  • jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

公共的声明 :
公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密.

私有的声明 :
私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。


定义一个payload:

{  "sub": "1234567890",  "name": "John Doe",  "admin": true}
将其进行base64加密,得到JWT的第二部分。
eyJzdWIiOiIxMjM0NTY3ODkwIiwgIm5hbWUiOiJKb2huIERvZSIsImFkbWluIjp0cnVlfQ

signature

这个签证信息由三部分组成:

  • header (base64后的)
  • payload (base64后的)
  • secret

这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。

(1)将上面的两个编码后的字符串都用点.连接在一起(头部在前),就形成了:       

eyJ0eXBlIjoiSldUIiwiYWxnIjoiSFMyNTYifQ.eyJzdWIiOiIxMjM0NTY3ODkwIiwgIm5hbWUiOiJKb2huIERvZSIsImFkbWluIjp0cnVlfQ

(2)我们将上面拼接完的字符串用HS256算法进行加密。加密时,还需要提供一个密钥(secret)。如果我们就用字符串secret作为密钥的话,那么就得到我们加密后的内容:
tHK2c4MuRFi_MXwCq3zqL1q-_GXfVmUW4LDi08xZTt4

(3) 将编码过后的hearder,payload ,Signature 用点号连接起来就是jwt的token

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

注意:secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,需要妥善保存,一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。


JSON Web Token 的工作流程

在用户使用证书或者账号密码登入的时候一个 JSON Web Token 将会返回,同时可以把这个 JWT 存储在local storage、或者 cookie 中,用来替代传统的在服务器端创建一个 session 返回一个 cookie。

2016-08-20_22:39:23.jpg

当用户想要使用受保护的路由时候,应该要在请求得时候带上 JWT ,一般的是在 header 的 Authorization 使用 Bearer 的形式,一个包含的 JWT 的请求头的 Authorization 如下:

Authorization: Bearer <token>

这是一钟无状态的认证机制,用户的状态从来不会存在服务端,在访问受保护的路由时候回校验 HTTP header 中 Authorization 的 JWT,同时 JWT 是会带上一些必要的信息,不需要多次的查询数据库。

这种无状态的操作可以充分的使用数据的 APIs,甚至是在下游服务上使用,这些 APIs 和哪服务器没有关系,因此,由于没有 cookie 的存在,所以在不存在跨域(CORS, Cross-Origin Resource Sharing)的问题。












原创粉丝点击