为了学习 OAuth(开放授权),我们先从怎么生成一个标准的 token 开始吧~
理论
jwt 的组成
一个标准的 token 是怎么样的,请看下面来自官方的一张图:
它是一个很长的字符串,中间用点 .
分隔成三个部分。
注意,jwt 内部是没有换行的,这里只是为了便于展示,将它写成了几行。
jwt 的三个部分依次如下:
- Header(头部)
- Payload(负载)
- Signature(签名)
写成一行,就是下面的样子:
Header.Payload.Signaturejwt - Header
Header 部分是一个 json 对象,描述 jwt 的元数据,通常是下面的样子:
1 | { |
上面代码中:
typ 属性表示这个令牌(token)的类型(type),jwt 令牌统一写为JWT
;
alg 属性表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256
);
最后,将上面的 json 对象使用 Base64URL 算法(原因见后文)转成字符串。
jwt - Payload
Payload 部分也是一个 json 对象,用来存放实际需要传递的数据。jwt 规定了 7 个官方字段,供选用:
- iss (Issuer):签发人
- exp (Expiration Time):过期时间
- sub (Subject):
- aud (Audience):
- nbf (Not Before):生效时间
- iat (Issued At):签发时间
jti (JWT ID):编号
两个没有中文注释的不好直译,更详细的解释,请看官方文档:
除了官方字段,你还可以在这个部分定义私有字段,如下面例子:
1 | { |
注意,jwt 默认是不加密的,任何人都可以读到,所以不要把秘密信息放在这个部分。
这个 json 对象也要使用 Base64URL 算法转成字符串。
jwt - Signature
Signature 部分是对前两部分的签名,防止数据篡改。
首先,需要指定一个密钥(secret)。
这个密钥只有服务器才知道,不能泄露给用户。
然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。
1 | HMACSHA256( |
生成测试:
1 | class Program |
如何验证我们生成的 token 是否符合标准呢?
请将生成的 token 复制到 https://jwt.io/#debugger 的 Encoded PASTE A TOKEN HERE
下的文本框,
然后留意文本框底下是 Signature Verified
还是 Invalid Signature
。
注意: 如果你修改了上面 const string Secret = "your-256-bit-secret"
的值,
那么需要将 Secret
的值复制到页面上 your-256-bit-secret
文本框处。
现在,我们已经知道 jwt 怎么制作了,
但当服务端接收到一个 jwt 的时候,我们需要判断是否合法,判断是否过期,以及从 jwt 中提取信息等,
这些一一都自己实现太麻烦了,因此使用别人实现好的类库吧~
使用微软类库
1 |
|
Go 实现
留坑,待填~ ^_^
jwt 的使用方式
客户端收到服务器返回的 jwt 后,
可以储存在 Cookie 里面,也可以储存在 localStorage。
此后,客户端每次与服务器通信,都要带上这个 jwt。
你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息 Authorization 字段里面。
1 | Authorization: Bearer <token> |
另一种做法是,跨域的时候,jwt 就放在 POST 请求的数据体里面。