python中的JWT

为了解决Http无状态问题,产生了cookie和session技术。

 传统的session技术解决了无状态问题,但是不能防止客户端的篡改,而且对于服务端要保存session,在数据量较大,业务规模增加时,还要解决多台服务器之间的session共享问题,使用redis或者memcached等方案。

产生可JWT技术可以解决用户篡改问题,服务器端产生的标识,使用算法加密,对标识签名。

再次收到服务器端的标识,就要检查签名。

这种方法在加密解密时,会消耗cpu计算资源,而且无法让浏览器自己检查过期数据,并且删除。

下边我将尝试解释一下jwt防篡改的原理。

JWT 全称(Json WEB Token)是一种采用Json方式安装传输信息的方式。

python下的实现的pyjwt

文档 : https://pyjwt.readthedocs.io/en/latest/

安装 : pip install pyjwt

先看以下代码:

import jwt

key = "secret"
token = jwt.encode({"test": "100"},key,"HS256")
print(token)
header,payload,signature = token.split(b".")
print(header)
print(payload)
print(signature)

 

显示

b'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0ZXN0IjoiMTAwIn0.p2dBskystmxOlIXrBCowu6DPcWQbRrZMT3hJV7iMY-8'
b'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9'
b'eyJ0ZXN0IjoiMTAwIn0'
b'p2dBskystmxOlIXrBCowu6DPcWQbRrZMT3hJV7iMY-8'

可以知道JWT由3段由点分割的部分组成。

它使用的编码是base64编码,我们导入以下

import jwt

key = "secret"
token = jwt.encode({"test": "100"},key,"HS256")
print(token)
header,payload,signature = token.split(b".")

import base64

def equal(b: bytes):
    """用来补齐被JWT去掉的等号"""
    rest = len(b) % 4
    return b + b'=' * rest

print("header=",base64.urlsafe_b64decode(equal(header)))
print("payout=", base64.urlsafe_b64decode(equal(payload)))
print("signature", base64.urlsafe_b64decode(equal(signature)))

 

显示:

header= b'{"typ":"JWT","alg":"HS256"}'
payout= b'{"test":"100"}'
signature b'\xa7gA\xb2L\xac\xb6lN\x94\x85\xeb\x04*0\xbb\xa0\xcfqd\x1bF\xb6LOxIW\xb8\x8cc\xef'

可以看到,JWT中传输的token内容由三部分组成

  • header 是由数据类型和加密算法组成
  • payload 是传输的数据部分,
  • signature 部分就时签名,是由前两部分和加密算法实现的,看以下代码

下边是源码中的一部分,signing_input就是将前两部分转为JSON格式,再使用base64编码,连接起来,传入下边的方法中,alg_obj是方法,key是预处理key

signing_input = b'.'.join(segments)
        try:
            alg_obj = self._algorithms[algorithm]
            key = alg_obj.prepare_key(key)
            signature = alg_obj.sign(signing_input, key)

我们模仿一下,可得

import jwt

# Create your tests here.

key = "secret"
token = jwt.encode({"test": "100"},key,"HS256")
header,payload,signature = token.split(b".")
print(signature)

import base64

# def equal(b: bytes):
#     """用来补齐被JWT去掉的等号"""
#     rest = len(b) % 4
#     return b + b'=' * rest

# print("header=",base64.urlsafe_b64decode(equal(header)))
# print("payout=", base64.urlsafe_b64decode(equal(payload)))
# print("signature", base64.urlsafe_b64decode(equal(signature)))

from jwt import algorithms
alg = algorithms.get_default_algorithms()["HS256"]
newkey = alg.prepare_key(key)
signature_input = b".".join([header,payload])
signature = alg.sign(signature_input,newkey)

print(base64.urlsafe_b64encode(signature))

 

显示,可以看到

b'p2dBskystmxOlIXrBCowu6DPcWQbRrZMT3hJV7iMY-8'
b'p2dBskystmxOlIXrBCowu6DPcWQbRrZMT3hJV7iMY-8='

所以在密码相同时,传输相同的信息,得到的值是一样的。

密码要足够强,且要足够安全。可以在测试下改变内容,看签名会不会改变。

import jwt

# Create your tests here.

key = "secret"
token = jwt.encode({"test": "100"},key,"HS256")
header,payload,signature = token.split(b".")
print(signature)

import base64

# def equal(b: bytes):
#     """用来补齐被JWT去掉的等号"""
#     rest = len(b) % 4
#     return b + b'=' * rest

# print("header=",base64.urlsafe_b64decode(equal(header)))
# print("payout=", base64.urlsafe_b64decode(equal(payload)))
# print("signature", base64.urlsafe_b64decode(equal(signature)))
token = jwt.encode({"test": "1000"},key,"HS256") # 改变payload内容
header,payload,signature = token.split(b".")

from jwt import algorithms
alg = algorithms.get_default_algorithms()["HS256"]
newkey = alg.prepare_key(key)
signature_input = b".".join([header,payload])
signature = alg.sign(signature_input,newkey)

print(base64.urlsafe_b64encode(signature))

可以看到签名变了

b'p2dBskystmxOlIXrBCowu6DPcWQbRrZMT3hJV7iMY-8'
b'uCmPr1eOuLz8IDLQfN8t_DsyrB9PYfdvdueeHSBWN04='

 

经过以上测试,可以知道,数据在使用JWT传输时,是明文传输的,注意不要传输敏感数据。

JWT的防篡改还可以使用公钥,私钥,来防止用户被劫持的可能性。

在用户登陆成功后可以使用JWT技术,登录后给用户JWT,用户发请求时加上jwt,服务器校验签名,通过就允许访问,在单点登陆时广泛应用。

 

转载于:https://www.cnblogs.com/rprp789/p/10017781.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值