文章插图
JWT 的诞生并不是解决 CSRF 跨域攻击,而是解决跨域认证的难题 。
举例来说,A 网站和 B 网站是同一家公司的关联服务 。现在要求,用户只要在其中一个网站登录,再访问另一个网站就会自动登录,这应该如何实现呢?
一种解决方案是 session 数据持久化,写入数据库或别的持久层 。各种服务收到请求后,都向持久层请求数据 。这种方案的优点是架构清晰,缺点是工程量比较大 。另外,持久层万一挂了,就会单点失败 。
另一种方案是服务器索性不保存 session 数据了,所有数据都保存在客户端,每次请求都发回服务器 。
JWT 就是这种方案的一个优秀代表 。
文章插图
JWT 如何生成?JWT 其实就是一个字符串,比如下面这样
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
仔细观察,会发现它里面有三个
.
,以.
为分界,可以将 JWT 分为三部分 。文章插图
- 第一部分:头部(Header)
- 第二部分:载荷(Payload)
- 【手绘10张图,把CSRF跨域攻击、JWT跨域认证说得明明白白的】第三部分:签名(Signature)
文章插图
5.1 头部(Header)JWT 的头部承载两部分信息:
- 声明类型:这里是 JWT
- 声明加密的算法:通常直接使用 Hmac SHA256
{
"typ": "JWT",
"alg": "HS256"
}
然后将头部进行 Base64URL 算法编码转换,构成了第一部分
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
5.2 载荷(Payload)载荷,同样也是个 JSON 对象,它是存放有效信息的地方,但不建议存放密码等敏感信息 。
JWT 规定了7个官方字段,供选用:
- iss (issuer):签发人
- exp (expiration time):过期时间
- sub (subject):主题
- aud (audience):受众
- nbf (Not Before):生效时间
- iat (Issued At):签发时间
- jti (JWT ID):编号
注意,JWT 默认是不加密的,任何人都可以读到,所以不要把秘密信息放在这个部分 。
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
然后将其进行 Base64URL 算法转换,得到 JWT 的第二部分 。
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
5.3 签名(Signature)Signature 部分是对前两部分的签名,防止数据篡改 。
首先,需要指定一个密钥(secret) 。这个密钥只有服务器才知道,不能泄露给用户 。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名 。
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(
.
)分隔,就可以返回给用户 。文章插图
如何手动生成 JWT?如果你想手动生成一个 JWT 用于测试,有两种方法
第一种:使用 https://jwt.io/ 这个网站。
我使用前面的 header 和 payload,然后使用 secret 密钥:
Python
最后生成的 JWT 结果如下
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.3wGDum3_A8tAt1bdal5CpYbIUlpHfPQxs96Ijx883kI
文章插图
第二种:使用 Python 代码生成
首先安装一下 pyjwt 这个库
$pip install pyjwt
然后就可以在代码中使用它
import jwt
import datetime
import uuid
salt = 'minggezuishuai'
# 构造header ,这里不写默认的也是
推荐阅读
- 火把节是哪个民族的?
- 黑洞会不会把地球吞了 黑洞如果吞噬地球会怎么样
- 巴西整容很厉害吗 巴西整容狂魔
- 为什么动物都愿意和大象玩 大象与什么动物生活在一起
- 化妆|如果想要不化妆就很漂亮,那就一定把自己已拥有的容貌保持好
- 黑洞能把地球吞噬吗 黑洞的吞噬范围
- 和田玉籽料|旧藏·和田玉籽料太平有象把件
- 【钦春语录】张冉:把自己变成了村里人
- 终于有人把常用的三种通讯方式:RS485、RS232、RS422讲明白了
- excel批量拆分工作簿,用VBA一键拆分,把数据分解到N个工作簿