当前位置: 首页 > 后端技术 > Python

5分钟,快速入门PythonJWT接口认证

时间:2023-03-25 21:47:35 Python

1.前言为了防止爬取或者限流,大部分API在后台写接口的时候都会进行权限认证。只有认证通过,即数据正常且未过期,才会返回数据,否则直接报错。本文以Django为例,说说后端JWT接口认证的操作流程2.JWT介绍JWT全称为JSONWebToken,是目前主流的跨域认证方案。数据结构由3部分组成,以“.”分隔在中间。分别是:HeaderHeaderPayloadLoadSignatureSignature#JWT数据的格式#组成方法:header.load.signatureHeader.Payload.Signature其中Header用于设置签名算法和token类型,默认签名算法为“HS256”,token类型可以设置为“JWT”Payload用于设置传输的数据,包括:ississuer,expexpirationtime,iatissuingtime等。Signature用于对Header和Payload进行签名,以及默认的签名算法是HeaderAlgorithm#JWTdatacomposition#Header中指定的算法。有效载荷。签名#Header:{"alg":"HS256","typ":"JWT"}#Payload:iss,exp,iat,etc.#Signature:SignatureSignature=HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)PS:base64UrlEncode与Base64算法相比,会省略结果中的“=”,将“+”替换为“-”,将“/”替换为“_”3。实战首先,在虚拟环境中安装JWT依赖包#安装jwt依赖包pip3installpyjwt然后,定义一个生成JWTToken的方法。需要注意的是,在生成JWTToken时,需要指定过期时间、加密方式等importtimeimportjwtfromdjango.confimportsettingsdefgenerate_jwt_token(user):"""生成一个JWTToken:paramuser::return:"""#设置token的过期时间戳#例如:设置一个7天的过期时间戳=int(time.time())+60*60*24*7#加密生成Token#加密方式:HS256returnjwt.encode({"userid":user.pk,"exp":timestamp},settings.SECRET_KEY,'HS256')接下来写一个认证类继承从“BaseAuthentication”基类,重写内部函数“authenticate()”,用JWT解密请求参数,并进行数据库查询,只有认证通过才返回数据,否则抛出异常importtimeimportjwtfromdjango.confimportsettingsfromdjango.contrib.authimportget_user_modelfromrest_frameworkimportexceptionsfromrest_framework.authenticationimportBaseAuthentication,get_authorization_headerUser=get_user_model()classJWTAuthentication(BaseAuthentication):"""CustomAuthenticationClass"""keyword='jwt'model=Nonedefget_modelif(self):not无:返回self.model来自rest_framework.authtoken.modelsimportToken返回Token"""可以使用自定义令牌模型,但必须具有以下属性。*key--标识令牌的字符串*user--令牌所属的用户"""defauthenticate(self,request):auth=get_authorization_header(request).split()ifnotauthorauth[0].lower()!=self.keyword.lower().encode():returnNoneiflen(auth)!=2:raiseexceptions.AuthenticationFailed("认证异常!")#jwt破解try:jwt_token=auth[1]jwt_info=jwt.decode(jwt_token,settings.SECRET_KEY,'HS256')#获取useriduserid=jwt_info.get("userid")#查询用户是否存在尝试:user=User.objects.get(pk=userid)returnuser,jwt_tokenexceptException:raiseexceptions.AuthenticationFailed("用户不存在")exceptjwt.ExpiredSignatureError:raiseexceptions.AuthenticationFailed("Sorry,thetokenhasexpired!")最后,在视图集ViewSet中,只需要在属性"authentication_classes"中指定认证列表即可fromrest_frameworkimportviewsetsfrom.modelsimport*from.serializersimport*from.authenticationsimport*classGoodsViewSet(viewsets.ModelViewSet):#所有商品数据queryset=Goods.objects.all()#序列化??serializer_class=GoodsSerializer#JWT授权authentication_classes=[JWTAuthentication]4.最后在实际项目中,一般在登录时生成JWTToken时,只需要在后续接口的请求头中设置JWTToken即可正常返回数据importrequestsurl="***.***.****"payload={}headers={'AUTHORIZATION':'jwteyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyaWQiOiJVTmJCRTJTRlNndm5DU0c3amdQZGJVIiwiZXhwIjoxNjI2MDk5NDA5fQ.cxXsRulEWWQotNpb7XwlZbISrrpb7rSRCjkLsyb8WDM'}response=requests.request("GET",url,headers=headers,data=payload)print(response.text)最近整理了几百G的Python学习资料,包含新手入门电子书、教程、源码等,免费分享给大家!想上“Python编程学习圈”,发“J”免费领取