- 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的一部分eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9Signaturejwt的第三部分是一个签证信息 , 这个签证信息由三部分组成:
- header(base64后的)
- payload(base64后的)
- secred
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);var signature = HMACSHA256(encodedString, 'secret'); // TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ将这三部分用“.”连接成一个完整的字符串 , 构成了最终的jwt:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ注意:secret是保存在服务器端的 , jwt的签发也是在服务端的 , secret就是用来进行jwt的签发和jwt的验证 , 所以它就是你服务端的私钥 , 在任何场景都不应该流露出去 , 一旦客户端得知这个secret , 那就意味着客户端可以自我签发jwt了应用
一般是在请求头里加入Authorization , 并加上Bearer标注:
fetch('api/user/1', {headers: {'Authorization': 'Bearer ' + token}})服务端会验证token , 如果验证通过就会返回相应的资源 , 整个流程就是这样
文章插图
总结
优点:
- 因为json的通用性 , 所以JWT是可以跨语言支持的 , 像C# , JAVAScript , NodeJS , php等许多语言都可以使用
- 因为由了payload部分 , 所以JWT可以在自身存储一些其它业务逻辑所必要的非敏感信息
- 便于传输 , jwt的构成非常简单 , 字节占用很小 , 所以它是非常便于传输的
- 它不需要在服务端保存会话信息 , 所以它易于应用的扩展
- 不应该在jwt的payload部分存储敏感信息 , 因为该部分是客户端可解密的部分
- 保护好secret私钥 。该私钥非常重要
- 如果可以 , 请使用https协议
推荐阅读
- web API接口及restful规范详解
- Fastjson 反序列化漏洞自动化检测
- 超详细 web前端开发:vue内部指令
- 如何使用 Flask 编写 Python Web API
- Node.js Web 框架 Adonis
- 详解Web应用的底层逻辑,掌握Spring框架开发的思路
- 9 个爱不释手的 JSON 工具
- 五分钟带你掌握web前端开发九个JavaScript小技巧
- 10分钟浅谈CSRF突破原理,Web安全的第一防线
- 使用Webmin管理您的Linux服务器
