当前位置:   article > 正文

Django jwt认证(基于pyjwt)

django jwt

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

  1. import jwt
  2. import datetime
  3. import djangoProject.settings
  4. def create_jwtToken(openid):
  5. expire_time = datetime.datetime.utcnow() + datetime.timedelta(days=7)
  6. headers = {
  7. 'typ': 'jwt',
  8. 'alg': 'HS256'
  9. }
  10. payload = {
  11. 'openid': openid,
  12. "exp": expire_time
  13. }
  14. result = jwt.encode(payload=payload, key=djangoProject.settings.SECRET_KEY, algorithm='HS256', headers=headers)
  15. return result
  16. def identify_token(token):
  17. try:
  18. verified_payload = jwt.decode(token, key=djangoProject.settings.SECRET_KEY, algorithms="HS256")
  19. #验证通过返回payload中的信息
  20. return verified_payload
  21. #不通过返回报错
  22. except jwt.ExpiredSignatureError:
  23. print('token已失效')
  24. return False
  25. except jwt.DecodeError:
  26. print('token认证失败')
  27. return False
  28. except jwt.InvalidTokenError:
  29. print('非法的token')
  30. 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是隐私信息就用乱码代替了):

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

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

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

    3.2.1单个函数添加认证

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

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

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

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

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

文件代码如下:

  1. from django.http import HttpResponse
  2. from django.urls import resolve
  3. from django.utils.deprecation import MiddlewareMixin
  4. from jwt_auth import jwt_auth
  5. class CheckFunctionMiddleware(MiddlewareMixin):
  6. #如果所有的视图函数都要检验token,那login界面也会无法触发,所以有部分函数是可以不需要验证token的
  7. #把这些函数的名字写在排除表中即可
  8. #如果函数是 def func(request):,在表中写func即可
  9. EXCLUDED_FUNCTIONS = ['login', 'getJwtToken', 'getToken']
  10. #这个函数在所有视图函数之前被触发,用来检验token的合法性刚好
  11. def process_request(self, request):
  12. jwtToken = request.META['HTTP_JWTTOKEN']
  13. #获取函数的名称
  14. path = request.path
  15. match = resolve(path)
  16. request_name = match.func.__name__
  17. #如果不在排除表中则触发
  18. if request_name not in self.EXCLUDED_FUNCTIONS:
  19. print("this func is not in the middleware dict")
  20. res=jwt_auth.identify_token(jwtToken)
  21. #检验不通过则返回错误
  22. if not res:
  23. return HttpResponse("TOKEN ERROR")

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

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

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

    

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号