JWT

JWT,Json Web Token,是一种基于token的json格式web认证的方法

在学习JWT前,先学习一些Token的知识

Session与Token

最开始,http是无状态的,服务器无法辨别http请求是否来自同一客户端;

之后,在交互式web应用中,服务器使用Session来辨别用户:初次向服务器请求时服务器会发送回来一个session id,之后客户端向服务器请求时带上这个字符串,服务器就能区分开了

但这种方法对服务器带来了很大的开销:每个客户只需要存储自己的session id,而服务器要保存所有客户的session id

那么,如何让每个客户端去保存这种session,服务器不去保存呢?关键就是验证

Token验证流程:

  • 点击登录时,服务器验证成功后会发送给用户一个token

  • 客户端存储Token(cookie或其他存储),再次请求时会带着token

  • 服务端收到请求,去验证token,如果验证成功则返回请求的数据

那么如何防止其他人去伪造Token呢?下面我们来了解一下JWT

JWT

结构:

  • Header(头信息)
  • Payload(消息体)
  • Signature(签名)

jwt即为:

urlsafe_b64encode(Header).urlsafe_b64encode(Payload).base64urlEncode(Signature)

则jwt看起来类似:

eyJhbGciIkpXVCJ9.eyJzdWIiOiIxwibdWV9.TJVA95OrM7E2cBab30RMHrHDcEf

这里解释一下什么是urlsafe_b64encode:

base64转码时会生成“+”,“/”,“=”这些被URL进行转码的特殊字符,如果希望在url中传输这些编码字符串,则要在base64编码基础上做一些处理

base64urlsafe编码的流程:

  • 明文使用BASE64进行加密
  • 在BASE64的基础上进行替换:
    • 把”+”替换成”-“
    • 把”/“替换成”_”
    • 长度不为四的倍数,补”=”

Header(头信息)

指定了该JWT使用的签名算法

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

HS256 表示使用了 HMAC-SHA256 来生成签名

Payload(消息体)

是token的具体内容;里面的内容可以是标准字段,还可自定义添加其他内容

标准字段:

iss:jwt的签发者
sub:jwt所面向的用户
aud:接收方
exp:过期时间;需大于签发时间
nbf:定义在什么时间之前,该jwt都是不可用的
iat:jwt的签发时间
jti:JWT ID

Signature(签名)

  • 分别用baseUrlEncode()编码Header和Payload,用小数点’.’将编码后的两部分连接起来
  • 使用Header中声明的加密方式进行加盐(key)组合加密;key保存在服务器端

签名的目的:

签名实际上是对Header和Payload的内容进行签名;如果有人对Header以及Payload的内容解码之后进行修改,再进行编码的话,那么新的Header和Payload的签名和之前的签名就将是不一样的。而且,如果不知道服务器加密的时候用的密钥的话,得出来的签名也一定会是不一样的。

秘钥(key)一旦泄露,客户端即可自我签发jwt

python3中的JWT模块

源地址:

https://github.com/jpadilla/pyjwt/

首先安装模块:

pip install PyJWT

导入:

import jwt

生成jwt:

encoded = jwt.encode({'some': 'payload'}, 'secret', algorithm='HS256')

解析jwt:

decoded = jwt.decode(encoded, 'secret', algorithms=['HS256'])

如果不知道秘钥的话,可以使用python的base64模块来进行编码和解码jwt的Header与Payload部分:

import base64

encode_str = base64.urlsafe_b64encode(b'abcd').decode('utf-8')
decode_str = base64.urlsafe_b64decode('YWJjZA==').decode('utf-8')

print('经base64urlsafe编码后的结果为: ', encode_str)
print('经base64urlsafe解码后的结果为: ', decode_str)

JWT安全

可以使用暴力破解的办法对key进行破解,以验证网站token的安全性。比如这个工具:

https://github.com/brendan-rius/c-jwt-cracker

除了用python或其他语言的模块,下面这个网站也可以解析出token的header和payload;还可进行token的生成:

https://jwt.io/

参考:

https://www.jianshu.com/p/af8360b83a9f

https://www.jianshu.com/p/576dbf44b2ae

https://www.helplib.com/GitHub/article_149904

https://www.cnblogs.com/moyand/p/9047978.html

https://www.cnblogs.com/kidsitcn/p/6901431.html