在开始之前先对 JWT 做个简单介绍:from: https://www.jianshu.com/p/164c3ff9033f
JWT生成的Token是一个用两个点(.)分割的长字符串;
分割成的三部分分别是Header头部,Payload负载,Signature签名 即 Header.Payload.Signature
JWT是不加密的,任何人都可以读的到其中的信息,其中第一部分 Header 和第二部分 Payload 只是对原始输入的信息转成了base64编码,第三部分Signature是用header+payload+secret_key进行加密的结果。
因为JWT不会对结果进行加密,所以不要保存敏感信息在Header或者Payload中,
服务端也主要依靠最后的 Signature 来验证Token是否有效以及有无被篡改。
可以直接用 base64 对 Header 和 Payload 进行解码得到相应的信息。
服务端在有秘钥的情况下可以直接对JWT生成的Token进行解密,解密成功说明Token正确,且数据没有被篡改。
当然我们前文说了JWT并没有对数据进行加密,如果没有secret_key也可以直接获取到Payload里边的数据,只是缺少了签名算法无法验证数据是否准确,pyjwt也提供了直接获取Payload数据的方法,如下
>>> 这里传了三部分内容给 JWT 的 encode 方法
>>> 第一部分是一个Json对象,称为Payload,主要用来存放有效的信息,例如用户名,过期时间等等所有你想要传递的信息
>>> 第二部分是一个秘钥字串,这个秘钥主要用在下文Signature签名中,服务端用来校验Token合法性,这个秘钥只有服务端知道,不能泄露
>>> 第三部分指定了Signature签名的算法
>>>
>>>
>>> import jwt
>>> import base64
>>>
>>> payload={"token_type":"access","user_id":"3","jti":"fba2ca559c214ada9cb903240dc4fa93","exp":1572603663}
>>> signing_key='dnB^kr8ho#shw$a8pqu3OAqFb@C8q&mZ'
>>> algorithm = 'HS256'
>>> token = jwt.encode(payload, signing_key, algorithm=algorithm)
>>>
>>> token
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwianRpIjoiZmJhMmNhNTU5YzIxNGFkYTljYjkwMzI0MGRjNGZhOTMiLCJ1c2VyX2lkIjoiMyIsImV4cCI6MTU3MjYwMzY2M30.F-zOc4Vxn-2i6zP1_Ej9M8hClngmeu0Ih9LI7iWTa_E'
>>>
>>> jwt.decode(token, signing_key, algorithms=algorithm, verify=True)
{u'token_type': u'access', u'user_id': u'3', u'jti': u'fba2ca559c214ada9cb903240dc4fa93', u'exp': 1572603663}
>>>
>>>
>>> 服务端在有秘钥的情况下可以直接对JWT生成的Token进行解密,解密成功说明Token正确,且数据没有被篡改
>>> 当然我们前文说了JWT并没有对数据进行加密,如果没有secret_key也可以直接获取到Payload里边的数据,只是缺少了签名算法无法验证数据是否准确,
>>> pyjwt也提供了直接获取Payload数据的方法,如下
>>> jwt.decode(token, verify=False)
{u'token_type': u'access', u'user_id': u'3', u'jti': u'fba2ca559c214ada9cb903240dc4fa93', u'exp': 1572603663}
>>>
>>> 修改 token, 然后再去 decode token 会报错 Signature verification failed
>>> token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwianRpIjoiZmJhMmNhNTU5YzIxNGFkYTljYjkwMzI0MGRjNGZhOTMiLCJ1c2VyX2lkIjoiMyIsImV4cCI6MTU3MjYwMzY2M31.F-zOc4Vxn-2i6zP1_Ej9M8hClngmeu0Ih9LI7iWTa_E'
>>> jwt.decode(token, signing_key, algorithms=algorithm, verify=True)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/root/myprojectenv/archiver_env/local/lib/python2.7/site-packages/jwt/api_jwt.py", line 92, in decode
jwt, key=key, algorithms=algorithms, options=options, **kwargs
File "/root/myprojectenv/archiver_env/local/lib/python2.7/site-packages/jwt/api_jws.py", line 156, in decode
key, algorithms)
File "/root/myprojectenv/archiver_env/local/lib/python2.7/site-packages/jwt/api_jws.py", line 223, in _verify_signature
raise InvalidSignatureError('Signature verification failed')
jwt.exceptions.InvalidSignatureError: Signature verification failed
>>>
>>>
>>> --------------------------------------
root@robert-Ubuntu:/media/sf_WorkSpace/HelloNG/src/testcode/djangoTest/robappdj# python
Python 2.7.12 (default, Oct 8 2019, 14:14:10)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import base64
>>> base64.b64decode('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9')
'{"alg":"HS256","typ":"JWT"}'
>>>
>>> base64.b64decode('eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwidXNlcl9pZCI6IjIiLCJqdGkiOiJmYmEyY2E1NTljMjE0YWRhOWNiOTAzMjQwZGM0ZmE5MyIsImV4cCI6MTU3MjYwMzY2M30==')
'{"token_type":"access","user_id":"2","jti":"fba2ca559c214ada9cb903240dc4fa93","exp":1572603663}'
>>>
>>>
版权声明:本文为cpxsxn原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。