Protogalaxy

Planet #0

PHSS-Core开发日志#5 Token的设计#1

由于PHSS的前后端分离特性,在设计PHSS的安全系统的时候了解到了JWT(JSON Web Token)策略,经过了一番权衡,处于对扩展性与易用性的需求,我决定使用JWT鉴权体系。由于JWT的特性,很多信息都将由Token来承载,所以Token的设计也成为了必须关注的一个点。以下关于JWT规约的内容译自jwt.io

在JWT规约中,Token主要由三部分组成,分别是:

  1. Header
  2. Payload
  3. Signature

Header(头)

Header通常由两部分组成,Token的类型与使用的加密算法,比如SHA256,RSA或者AES256。

{
  "alg": "HS256",
  "typ": "JWT"
}

将此段进行Base64编码,作为Token的第一部分

Payload(载荷)

Token的第二部分是包含claims的Payload。Claims(声明)描述了各种实体(比如用户)与其他各种元数据的内容。Claim有三种类型:registered,public与private。

  • Registered claims

一般来说,为了使Token更具有实用性与可交互性,Registered claims有一些非强制的内容规约,例如 iss (issuer发行者),exp (expiration time过期时间),sub (subject主题),aud(audience受众)以及其他一些内容。

  • Public claims

可以被任意定义,但是为了避免冲突,这些声明应该在IANA JSON Web Token Registry中被定义,或者在防冲突命名空间中作为URI定义。

  • Private claims

定制型声明,一般用于在统一使用的两方之中共享信息并且claim的类型既不是registered也不是public

{
  "sub": "1234567890",
  "name": "Arthur Lee",
  "admin": true
}

然后将Payload进行Base64Url编码,作为Token的第二部分。

Signature(签名)

要创建Signature,必须使用已编码的header与Payload,一个Secret(密钥),在header中声明的加密算法,然后进行签名。

例如,你要使用HMAC SHA256算法,那么签名可以按照如下形式创建:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

签名用来验证信息是否在传输过程中改变,并且,在使用private claim的情况下,还可以验证JWT的发出者。

 

Putting all together

最终输出的Token形式是可以在HTML与HTTP环境下便捷传输的,被dot分隔的三个Base64-URL字符串。与基于XML的标准(例如SAML)相比,JWT显得更为紧凑。

以下示例展示了一个符合JWT标准的Token,含有已编码的header与payload,和一个密钥加密的签名:

Encoded JWT

 

发表评论