pyJWT
Posted zzy-9318
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pyJWT相关的知识,希望对你有一定的参考价值。
现在用JWT 非对称加密太火了,怎么能不跟上潮流?否则销售都不好意思出去吹牛逼!
PyJWT是一个Python库,用来编码/解码JWT(JSON Web Token)的
1.定义:根据维基百科的定义,JSON WEB Token(JWT,读作 [/d??t/]),是一种基于JSON的、用于在网络上声明某种主张的令牌(token)。JWT通常由三部分组成: 头信息(header), 消息体(payload)和签名(signature)。
1.1头信息指定了该JWT使用的签名算法:
header = ‘{"alg":"HS256","typ":"JWT"}‘
1.2消息体包含了JWT的意图:
payload = ‘{"loggedInAs":"admin","iat":1422779638}‘//iat表示令牌生成的时间
1.3未签名的令牌由base64url
编码的头信息和消息体拼接而成(使用"."分隔),签名则通过私有的key计算而成
key = ‘secretkey‘ unsignedToken = encodeBase64(header) + ‘.‘ + encodeBase64(payload) signature = HMAC-SHA256(key, unsignedToken)
2.上代码:摘自https://www.cnblogs.com/liufei1983/p/8546505.html 写都不错,挺清晰的借鉴一下,不过项目里一般都是封装成装饰器,作为接口认证
import datetime, jwt, time from app.dao.userDao import UserDao from flask import jsonify from .. import common class Auth(): @staticmethod def encode_auth_token(user_id, login_time): """ 生成认证Token :param user_id: int :param login_time: int(timestamp) :return: string """ try: payload = { ‘exp‘: datetime.datetime.utcnow() + datetime.timedelta(days=0, seconds=10), ‘iat‘: datetime.datetime.utcnow(), ‘iss‘: ‘ken‘, ‘data‘: { ‘id‘:user_id, ‘login_time‘: login_time } } return jwt.encode( payload, ‘secret‘, algorithm=‘HS256‘ ) except Exception as e: return e @staticmethod def decode_auth_token(auth_token): """ 验证Token :param auth_token: :return: integer|string """ try: payload = jwt.decode(auth_token, ‘secret‘, options= {‘verify_exp‘:False}) if (‘data‘ in payload and ‘id‘ in payload[‘data‘]): return payload else: raise jwt.InvalidTokenError except jwt.ExpiredSignatureError: return "Token过期" except jwt.InvalidTokenError: return "无效的Token" def authenticate(self, username, password): """ 用户登录,登录成功返回token,写将登录时间写入数据库;登录失败返回失败原因 :param password: :return: json """ userDao = UserDao() user = userDao.search(username) if (user is None): return jsonify(common.falseReturn(‘‘, ‘找不到用户‘)) else: if (user.password == password): login_time = int(time.time()) token = self.encode_auth_token(user.username, login_time) return jsonify(common.trueReturn(token.decode(), ‘登陆成功‘)) else: return jsonify(common.falseReturn(‘‘, ‘密码不正确‘)) def identify(self, request): """ 用户鉴权 :return: list """ auth_header = request.headers.get(‘Authorization‘) if (auth_header): auth_tokenArr = auth_header.split(" ") if (not auth_tokenArr or auth_tokenArr[0]!= ‘jwt‘ or len(auth_tokenArr) != 2 ): result = common.falseReturn(‘‘,‘请传递正确的验证头信息‘) else: auth_token = auth_tokenArr[1] payload = self.decode_auth_token(auth_token) if not isinstance(payload, str): userDao = UserDao() user = userDao.search(payload[‘data‘][‘id‘]) if (user is None): result = common.falseReturn(‘‘, ‘找不到该用户信息‘) else: result = common.trueReturn(‘‘, ‘请求成功‘) else: result = common.falseReturn(‘‘, payload) else: result = common.falseReturn(‘‘,‘没有提供认证token‘) return result
代码说明:
authenticate: 根据用户名/密码,到DB中进行校验,如果是合法的用户名/密码,调用encode_auth_token生成token返回;username加入到token的payload中。
encode_auth_token: 生成token的函数,payload可以存储一些不敏感的信息,比如用户名等,但是不能存密码;还有指定签名算法和秘钥。
identify: 用户的请求需要携带token信息,这个函数对request进行校验,调用decode_auth_token完成的校验。
decode_auth_token: 调用jwt.decode进行token校验(要指定秘钥,秘钥和生成token的秘钥一样)
3.参数详解
exp是expires的简写,是用来指定token的生命周期
iss是issuer的简写,表明请求的实体,可以是发出请求的用户的信息
iss(签发者),exp(过期时间戳), sub(面向的用户), aud(接收方), iat(签发时间)
4.最简单的例子
加密
def _set_token(self, studentMids):
doc = {
‘relate_info‘: {‘Phone‘: Phone,‘secret‘:self.Secret},
‘exp‘: datetime.datetime.utcnow() + datetime.timedelta(seconds=JWTConfig.EXP)
}
encodeds = jwt.encode(
doc,
JWTConfig.SECRET_KEY,
algorithm=JWTConfig.ALGORITHM
)
return encodeds
解密(主要还要看你自己写的加密规则来解密)
token = request.headers.get(‘Authorization‘) decryptData = token.split(".")[1] + "=" * (4 - len(token.split(".")[1]) % 4) secret = osjson.loads(base64.b64decode(decryptData))[‘relate_info‘][‘secret‘] separator = encrypt(CUSTOMSECRET, "") res = secret[::-1].split(str(base64.b64encode(separator.encode(‘utf-8‘)),"utf-8"))
5.奉送一个写的不错,特别详细的博客链接https://blog.csdn.net/cruise_h/article/details/50888225
以上是关于pyJWT的主要内容,如果未能解决你的问题,请参考以下文章
使用 PyJWT 在 Python 中解码 Firebase JWT