jsonwebtoken

前言

由于我也只是JWT新手,今天在写一个小项目的时候用到了,就自己整理了一下。如下内容均为自己整理,资料来自官网标准少数博客。受限于自身技术水平,和翻译水平,难免有些错误,我已经尽可能避免,还是希望不要误导了别人。

JWT是一种新的认证机制,这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。

传统session面临的问题

  • session 每次进行验证,服务器都会做出记录,久而久之服务器压力很大
  • 由于记录多保存在服务器上,这意味着用户下次请求还必须要请求在这台服务器上,这也意味着限制了应用的扩展能力。
  • 可能受到CSRF攻击

token

Token验证是无状态的(stateless),并不需要在服务器上储存,所以解决了session可能面对的一些问题

JWT

一个JWT实际上是一个字符串由三部分构成 头部(header) 载荷(Payload) 和 签名(signature) 根据官方标准

部用于描述关于该JWT的最基本的信息,例如其类型以及签名所用的算法等,也可以被表示成一个JSON对象。

1
2
3
4
{
"typ": "JWT",
"alg": "HS256"(这里表示算法是HS256)
}

经过Base64编码之后得到eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 这就是JWT的header
Tips: Base64只是一种编码形式,不是加密

Payload

载荷就是存在有效信息的地方, There are three types of claims: registered, public, and private claims. 载荷有三种类型

Registered claims(注册声明)—推荐使用,但不是必须 [来源][https://tools.ietf.org/html/rfc7519#page-9]

  • iss (issuer) 该JWT的签发者
  • exp (expiration time) 什么时候过期,Unix时间戳
  • sub (subject) 该JWT所面向的用户
  • aud (audience) 接收该JWT的一方
  • “iat” (Issued At) jwt的签发时间
  • others

Public claims

我们所建立的公开资讯例如使用者姓名,不建议存放敏感信息

Private claims

发行者与订阅者自行沟通定义的Claims Name 与资料,Private Claim Names are subject to collision and should be used with caution.
不建议存放敏感信息
eg:

1
2
3
4
5
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}

经过base64编码之后 成为JWT的第二部分

1
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

Signature

将上面的两个编码后的字符串都用句号.连接在一起(头部在前),就形成了
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
最后,我们将上面拼接完的字符串用HS256算法进行加密。在加密的时候,我们还需要提供一个密钥(secret)。如果我们用secret作为密钥的话,那么就可以得到我们加密后的内容假设是TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ(这里我没跑程序,假设了一个值)

1
2
3
4
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)

最后把这三个部分用.链接就构成了JWT
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

适用场景

JWT适合用于向Web应用传递一些非敏感信息。例如在完成加好友的操作,还有诸如下订单的操作等等。
不应该在jwt的payload部分存放敏感信息,因为该部分是客户端可解码的部分。
再次强调base64是编码而非加密,所以直接解码直接可以拿到信息了。

结语

翻译查资料搞了挺久,自己收获很大,使用的话明天再说了…如有错误,欢迎指出,感谢阅读!