当前位置:   article > 正文

Python JWT原理机制_python jwt encode

python jwt encode

三种分页方式

  1. # 什么样接口要分页----》获取所有
  2. # 三种分页方式---》继承GenericAPIView,ListModelMixin
  3. -list方法---》

分页的使用  page.py

  1. from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination
  2. # 基本分页:正常的查第几页,每页显示多少条的方式---》常用
  3. class CommonPageNumberPagination(PageNumberPagination):
  4. #4 个类属性
  5. page_size = 2 #每页显示条数
  6. page_query_param = 'page' # 查询页码参数 ?page=10
  7. page_size_query_param = 'size' # ?page=3&size=5000
  8. max_page_size = 5 #可以通过size控制每页显示的条数,但是通过这个参数控制最多显示多少条
  9. # http://127.0.0.1:8000/books/?page=1&size=300000
  10. # 偏移分页
  11. class CommonLimitOffsetPagination(LimitOffsetPagination):
  12. default_limit = 2 # 每页显示多少条
  13. limit_query_param = 'limit' # 取多少条
  14. offset_query_param = 'offset' #从第0个位置偏移多少开始取数据
  15. max_limit = 5 # 最大限制条数
  16. # offset=6&limit=90000
  17. # http://127.0.0.1:8000/books/?limit=3&offset=3 # 从第三条开始取3条
  18. # limit_query_description = _('Number of results to return per page.')
  19. # 游标分页---》针对于大数据量分页效率高---》可控性差--->只能选择上一页和下一页,不能直接跳转到某一个
  20. class CommonCursorPagination(CursorPagination):
  21. cursor_query_param = 'cursor' # 查询的名字 等同于 page=xx
  22. page_size = 3 # 每页显示多少条
  23. ordering = 'id' # 排序规则,必须是表中有的字段,一般用id
  24. #http://127.0.0.1:8000/books/?cursor=cD0z

views.py

  1. from rest_framework.generics import GenericAPIView
  2. from rest_framework.viewsets import GenericViewSet
  3. from rest_framework.mixins import ListModelMixin
  4. from .models import Book
  5. from .serializer import BookSerializer
  6. # 三种分页方式:
  7. from .page import CommonPageNumberPagination as PageNumberPagination
  8. from .page import CommonLimitOffsetPagination
  9. from .page import CommonCursorPagination
  10. class BookView(GenericAPIView,ListModelMixin):
  11. class BookView(GenericViewSet, ListModelMixin):
  12. queryset = Book.objects.all()
  13. serializer_class = BookSerializer
  14. pagination_class= CommonCursorPagination

继承APIView实现分页

  1. # APIView实现分页
  2. from rest_framework.views import APIView
  3. from rest_framework.viewsets import ViewSet
  4. from rest_framework.response import Response
  5. class BookView(ViewSet):
  6. def list(self,request):
  7. books=Book.objects.all()
  8. # 分页
  9. # paginator=PageNumberPagination()
  10. paginator=CommonLimitOffsetPagination()
  11. #分页过后的数据
  12. qs=paginator.paginate_queryset(books,request,self)
  13. #序列化
  14. ser=BookSerializer(qs,many=True)
  15. # 第一种方式:每页总条数,上一页,下一页
  16. # return Response(ser.data)
  17. # 第二种:自己凑
  18. # return Response({
  19. # 'count':books.count(),
  20. # 'next': paginator.get_next_link(),
  21. # 'previous':paginator.get_previous_link(),
  22. # 'results': ser.data
  23. # })
  24. # 第三种;直接使用分页类的方法
  25. return paginator.get_paginated_response(ser.data)

JWT原理

  1. # jwt:Json web token
  2. # cookie,session,token
  3. -cookie是存放在客户端浏览器的键值对
  4. -session是存放在服务端的键值对
  5. 客户端:sessionId:asdfasdf----》放到cookie中
  6. 服务端:
  7. asdfasdf:{id:3,name:lqz}
  8. dddddd:{id:4,name:pyy}
  9. -token: 字符串:分三段
  10. -第一段:头--》公司信息,加密方式。。。
  11. -第二段:荷载--》放用户信息---->{id:3,name:lqz}
  12. -第三段:签名---》把第一段和第二段通过某种加密方式+秘钥加密得到一个字符串 asdfads
  13. -把三段使用base64编码后拼到一起 dasfasd.asdfasdasd.asdfads
  14. -【token 的签发】---》登录成功后,服务端生成
  15. -把token串给前端---》前端拿着
  16. -后面前端只要发请求,就携带token串到后端
  17. -【token的验证】--》拿到第一段和第二段使用同样的加密方式+秘钥再加密---》得到字符串跟第三段比较,如果一样,表示没有被篡改,如果不一样,表明被篡改了,token不能用了
  18. -如果没有被篡改,取出第二段 当前登录用户的信息 id
  19. #jwt:Json web token---》只针对于web方向的token方式验证
  20. # token典型样子
  21. eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
  22. # jwt组成
  23. -1 header---》{'typ': 'JWT','alg': 'HS256'}---》通过bas64编码后----》eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
  24. -2 payload---》荷载---》真正用户的数据
  25. {
  26. "sub": "1234567890", # 过期时间
  27. "id":3
  28. "name": "John Doe",
  29. "admin": true
  30. }
  31. -3 signature---》签名
  32. header (base64后的)
  33. payload (base64后的)
  34. secret
  35. # base64的编码和解码
  36. -base64的长度一定是4的倍数,如果不到用=补齐
  37. import json
  38. import base64
  39. # d={'typ': 'JWT','alg': 'HS256'}
  40. # s=json.dumps(d)
  41. # print(s)
  42. #把字符串进行b64编码
  43. # res=base64.b64encode(bytes(s,encoding='utf-8'))
  44. # print(res)
  45. #把b64编码的字符串,解码
  46. # b=b'eyJ0eXAiOiAiSldUIiwgImFsZyI6ICJIUzI1NiJ9'
  47. # res=base64.b64decode(b)
  48. # print(res)
  49. # 开发中使用jwt认证的重点
  50. -签发token---》登录
  51. -认证token---》认证类

Django中快速使用JWT

  1. # https://github.com/jpadilla/django-rest-framework-jwt
  2. # https://github.com/jazzband/djangorestframework-simplejwt
  3. # 用法95%相似
  4. #安装
  5. pip3 install djangorestframework-jwt
  6. # 快速使用---》使用的表是django的auth的user表---》创建一个用户
  7. # 只需要在路由中配置---》auth的user表中有用户
  8. from rest_framework_jwt.views import obtain_jwt_token
  9. urlpatterns = [
  10. path('login/', obtain_jwt_token),
  11. ]

修改返回格式

  1. # 登录成功返回格式:{code:100,msg:"登录成功",token:asdfasdf,username:lqz}
  2. # 写一个函数,在配置文件配置
  3. def jwt_response_payload_handler(token, user=None, request=None):
  4. return {'code': 100, 'msg': '登陆成功', 'token': token, 'username': user.username}
  5. # 配置文件配置
  6. JWT_AUTH = {
  7. 'JWT_RESPONSE_PAYLOAD_HANDLER': 'app01.utils.jwt_response_payload_handler',
  8. }
'
运行

JWT的验证

  1. # 只需要在视图类中加入一个认证类,一个权限类
  2. class BookView(ViewSet):
  3. # 认证类
  4. authentication_classes = [JSONWebTokenAuthentication,]
  5. # 权限类
  6. permission_classes = [IsAuthenticated,]
  7. # 需要在请求头中携带token
  8. -请求头中key:Authorization
  9. -请求头的value值:jwt 空格 token串

自定义用户表签发Token

  1. 自己定义用户表,实现签发Token功能----登录接口
  2. from rest_framework_jwt.settings import api_settings
  3. jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
  4. jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
  5. from rest_framework.decorators import action
  6. class UserView(ViewSet):
  7. @action(methods=['POST'],detail=False)
  8. def login(self, request):
  9. username = request.data.get('username')
  10. password = request.data.get('password')
  11. user = UserInfo.objects.filter(username=username, password=password).first()
  12. if user:
  13. # 登录成功---》签发token
  14. payload = jwt_payload_handler(user) # 根据当前登录用户获取荷载
  15. print(payload)
  16. token = jwt_encode_handler(payload) # 根据荷载生成token
  17. return Response({'code': 100, 'msg': '登录成功', 'token': token})
  18. else:
  19. return Response({'code': 101, 'msg': '用户名或密码错误'})

自定义认证类验证Token

  1. from rest_framework_jwt.settings import api_settings
  2. from rest_framework import exceptions
  3. from .models import UserInfo
  4. jwt_decode_handler = api_settings.JWT_DECODE_HANDLER
  5. jwt_get_username_from_payload = api_settings.JWT_PAYLOAD_GET_USERNAME_HANDLER
  6. class LoginAuth(BaseAuthentication):
  7. def authenticate(self, request):
  8. # 1 取出 token
  9. jwt_value = request.META.get('HTTP_TOKEN')
  10. # 2 验证token是否合法
  11. # try:
  12. # payload = jwt_decode_handler(jwt_value)
  13. # except jwt.ExpiredSignature:
  14. # msg = 'token过期了'
  15. # raise exceptions.AuthenticationFailed(msg)
  16. # except jwt.DecodeError:
  17. # msg = 'token解码错误'
  18. # raise exceptions.AuthenticationFailed(msg)
  19. # except jwt.InvalidTokenError:
  20. # msg = '解析token未知错误'
  21. # raise exceptions.AuthenticationFailed(msg)
  22. try:
  23. payload = jwt_decode_handler(jwt_value)
  24. except Exception:
  25. raise exceptions.AuthenticationFailed('token错误')
  26. print(payload) # 荷载---》user_id
  27. user = UserInfo.objects.filter(pk=payload['user_id']).first()
  28. return user, jwt_value
声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号