转载本文请联系AirPython公众号.一、前言大家好,我是安国!大多数API在后端写接口的时候,为了防止爬取或者限流,都会进行权限认证。否则直接报错。本文以Django为例,讲一下后端JWT接口认证的操作过程。2、JWT简介JWT全称为JSONWebToken,是目前主流的跨域认证方案。数据结构由三部分组成,中间部分用“.”分隔,分别是:HeaderHeaderPayloadLoadSignatureSignature#JWT数据格式#组成方法:header.load.signatureHeader.Payload.Signature其中Header用于设置签名算法和token类型,默认签名算法为“HS256”,token类型可设置为“JWT”。Payload用于设置传输的数据,包括:ississuer,exp过期时间,iat发行时间等Signature用于对Header和Payload进行签名,默认使用签名算法为指定的算法Header#JWT数据组成#Header.Payload.Signature#Header:{"alg":"HS256","typ":"JWT"}#Payload:iss,exp,iat等#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:"""#Settokenexpirationtimestamp#Forexample:set7-dayexpirationtimestamp=int(time.time())+60*60*24*7#EncrypttogenerateToken#Encryptionmethod:HS256returnjwt.encode({"userid":user.pk,"exp":timestamp},settings.SECRET_KEY,'HS256')Next,writeanauthenticationclassthatinheritsfromthe"BaseAuthentication"baseclassandrewritetheinternalfunction"authenticate()」,对请求参数进行JWT解密,并进行数据库查询,只有认证通过才返回数据,否则抛出异常importtimeimportjwtfromdjango.confimportsettingsfromdjango.contrib.authimportget_user_modelfromrest_frameworkimportexceptionsfromrest_framework.authenticationimportBaseAuthentication,get_authorization_headerUser=get_user_model()classJWTAuthentication(BaseAuthentication):"""Customauthenticationclass"""keyword='jwt'model=Nonedefget_model(self):ifself.modelisnotNone:returnself.modelfromrest_framework.authtoken.modelsimportTokenreturnToken"""Acustomtokenmodelmaybeused,butmusthavetheuserthefollowingproperties.*key--Thestringwuseren*buchenkingtoken"defauthenticate(self,request):auth=get_authorization_header(request).split()ifnotauthorauth[0].lower()!=self.keyword.lower().encode():returnNoneiflen(auth)!=??2:raiseexceptions.AuthenticationFailed("Authenticationexception!")#jwtdecodingtry:jwt_token=auth[1]jwt_info=jwt.decode(jwt_token,settings.SECRET_KEY,'HS256')#getuseriduserid=jwt_info.get("userid")#查询是否是用户已存在)最后,在视图集ViewSet中,只需要在属性"authentication_classes"中指定认证列表fromrest_frameworkimportviewsetsfrom.modelsimport*from.serializersimport*from.authenticationsimport*classGoodsViewSet(viewsets.ModelViewSet):#Allcommoditydataqueryset=Goods.objects.all()#Serializationserializer_class=GoodsSerializer#JWTauthorizationauthentication_classes=[JWTAuthentication]4。最后,在实际项目中,一般在登录时生成JWTToken,在后续接口中,只需要在请求头中设置JWTToken,即可正常返回数据importrequestsurl="***.***.****"payload={}headers={'AUTHORIZATION':'jwteyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyaWQiOiJVTmJCRTJTRlNndm5DU0c3amdQZGJVIiwiZXhwIjoxNjI2MDk5NDA5fQ.cxXsRulEWWQotNpb7XwlZbISrrpb7rSRCjkLsyb8WDM'}response=requests.request("GET",url,headers=headers,data=payload)打印(response.text)
