Django jwt认证(基于pyjwt)

1.前置准备

     pip install pyjwt(默认安装最新版)

2.jwt三个部分的介绍

   2.1Header

         头部包含两部分,一个是token的类型,另一个是加密类型

           

    2.2payload

         payload是装载在jwt中的一些有效信息,是可以自定义的一部分,比如我想在验证完这个jwt之后直接取到用户的id,昵称之类的,就可以放在这个地方,怎么取到后面会说

         

       这里放的是wx小程序里main获取的openid和过期时间

   2.3signature

        这个部分是整个jwt最核心的地方,他需要经过base64url编码的header,payload,以及我们提供的一把密钥,通过header中指定的算法(这里是HS256)算出的一个字符串

得到header,payload和signature后用‘.’连接就得到了jwt 

eg:

eyJhbGciOiJIUzI1NiIsInR5cCI6Imp3dCJ9.eyJvcGVuaWQiOiIoJ29RdVdsNVdGeWdscEpVb2tJQ2N5U25PZWJ3TWsnLCkiLCJleHAiOjE3MDkyMTM4NDZ9.2BT5AhrkYB5ww0jetD7qIz9DntXmXbYYdOTHdxMO9Wo

   2.4解密原理

1.后端接收到前端传来的token

2.对token进行分割(分成header,payload,signature)

3.对payload进行base64url解密得到payload中的信息

4.将header和payload拼接后进行HS256加密看是否等于base64解密的signature,如果相等则验证成功

3.1代码示例

   在根目录下创建文件夹jwt.auth,创建py文件jwt.auth

文件代码如下:

一个用来创建jwt,一个用来验证jwt

import jwt
import datetime
import djangoProject.settings

def create_jwtToken(openid):
    expire_time = datetime.datetime.utcnow() + datetime.timedelta(days=7)
    headers = {
        'typ': 'jwt',
        'alg': 'HS256'
    }

    payload = {
        'openid': openid,
        "exp": expire_time
    }
    result = jwt.encode(payload=payload, key=djangoProject.settings.SECRET_KEY, algorithm='HS256', headers=headers)
    return result


def identify_token(token):
    try:
        verified_payload = jwt.decode(token, key=djangoProject.settings.SECRET_KEY, algorithms="HS256")
#验证通过返回payload中的信息
        return verified_payload
#不通过返回报错
    except jwt.ExpiredSignatureError:
        print('token已失效')
        return False
    except jwt.DecodeError:
        print('token认证失败')
        return False
    except jwt.InvalidTokenError:
        print('非法的token')
        return False

如果是2.x的python,create_jwtToken里面的result要写成

 result = jwt.encode(payload=payload, key=djangoProject.settings.SECRET_KEY, algorithm='HS256', headers=headers).decode("utf-8")

3.x版本都是unicode就不用decode了    

调用示例:

打印的结果(openid是隐私信息就用乱码代替了):

eyJhbGciOiJIUzI1NiIsInR5cCI6Imp3dCJ9.eyJvcGVuaWQiOiIoJ29RdVdsNVdGeWdscEpVb2tJQ2N5U25PZWJ3TWsnLCkiLCJleHAiOjE3MDkyNzI2NDJ9.EZRwUn6fF7F5_qwFHxITu04blp6z6jP7L-BbAViCnhY
{'openid': "('dafadfasfsdfafda',)", 'exp': 1709272642}

好了,现在我们已经有了生成jwt和验证jwt的方法,那具体在函数里面该怎么认证呢?

3.2jwt认证方式以及通过中间件添加全局认证

    3.2.1单个函数添加认证

def func(request):
    #我的前端是以在header中添加参数jwttoken来传递的,所以获取方式如下
    jwtToken = request.META['HTTP_JWTTOKEN']
    #如果是用url参数的方式传递也可以,用相应的方法获取token就行了
    res=jwt_auth.identify_token(jwtToken)
        if not res:
           return HttpResponse("TOKEN ERROR")
    #后面写正常流程即可
    #...

正常的话不会有任何反应,如果有问题的话会报错,然后阻断后面的函数执行(报错的方法写在认证那里了)

  3.2.2通过中间件添加全局认证

         如果只有几个函数还可以挨个添加,但如果有几百个函数呢,我们不可能去每个函数里面都加这几句,这个时候就需要中间件来帮忙了

在根目录下创建软件包middleware,包中创建py文件check_function_middleware

文件代码如下:

from django.http import HttpResponse
from django.urls import resolve
from django.utils.deprecation import MiddlewareMixin
from jwt_auth import jwt_auth


class CheckFunctionMiddleware(MiddlewareMixin):
#如果所有的视图函数都要检验token,那login界面也会无法触发,所以有部分函数是可以不需要验证token的
#把这些函数的名字写在排除表中即可
#如果函数是 def func(request):,在表中写func即可
    EXCLUDED_FUNCTIONS = ['login', 'getJwtToken', 'getToken']
#这个函数在所有视图函数之前被触发,用来检验token的合法性刚好
    def process_request(self, request):
        jwtToken = request.META['HTTP_JWTTOKEN']
#获取函数的名称
        path = request.path
        match = resolve(path)
        request_name = match.func.__name__
#如果不在排除表中则触发
        if request_name not in self.EXCLUDED_FUNCTIONS:
            print("this func is not in the middleware dict")
            res=jwt_auth.identify_token(jwtToken)
#检验不通过则返回错误
            if not res:
               return HttpResponse("TOKEN ERROR")

接下来只要全局注册一下中间件就行了

在setting.py中(路径写成CheckFunctionMiddleware类的路径就行):

  至此,基本功能已经完成。

    

  • 12
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值