一、JWT认证

JWT构成

JWT分为三段式:头、体、签名(head、payload、sgin)

头和体是可逆加密的,让服务器可以反解析出user对象,签名是不可逆加密,保证整个token的安全性的。

头、体、签名三部分,都是采用JSON格式的字符串,进行加密,可逆加密一般蚕蛹base64算法,不可逆加密一般采用hash(md5)算法

  • 头中的内容是基本信息:项目信息等、
  1. {
  2. 'company': '项目信息',
  3. ...
  4. }
  • 体中的内容是关键信息:用户主键、用户名、签发时客户端信息(设备号,地址)、过期时间
  1. {
  2. 'user_id': 2,
  3. 'username': 'xiaoyang',
  4. ...
  5. }
  • 签名中的内容是安全信息:头的加密结果 + 体的加密结果 + 服务器不对外公开的安全码 进行md5加密
  1. {
  2. "head": "头的加密字符串",
  3. "payload": "体的加密字符串",
  4. "secret_key": "安全码"
  5. }

过期时间配置:

  1. import datetime
  2. JWT_AUTH={
  3. 'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7), # 过期时间,手动配置
  4. }

校验过程

  1. 将token按 ‘ . ’ 拆分为三段字符串
  2. 第一段:头加密字符串,一般不需要做任何处理
  3. 第二段:体加密字符串,要反解出用户主键,通过主键从User表中就能得到登录用户,过期时间和设备信息都是安全信息,确保token没有过期,且是同一设备来的
  4. 在用 第一段 + 第二段 + 服务器安全码 进行md5加密,与第三段 ”签名字符串“ 进行对比校验,通过后才能代表第二段校验得到的user对象是合法的登录用户

DRF项目的JWT认证开发流程

  1. 用账号密码访问登录接口,登录接口逻辑中调用签发token算法,得到token,返回给客户端,客户端自己存到Cookies中
  2. 校验token的算法应该写在认证类中(在认证类中调用),全局配置给认证组件,所有视图类请求,都会进行认证校验,所以请求带了token,就会反解析出user对象,在视图类中用request.user就能访问登录的用户。

第三方JWT认证

使用 JWT的第三方认证模块 django-rest-framework-jwk

安装:pip install djangorestframework-jwk

简单使用:

1、用户密码认证成功获取token

  1. # 首先创建超级用户 》》python manage.py createsuperuser
  2. from rest_framework_jwt.views import ObtainJSONWebToken, VerifyJSONWebToken, RefreshJSONWebToken
  3. # 基类:JSONWebTokenAPIView 继承了APIView
  4. # ObtainJSONWebToken,VerifyJSONWebToken,RefreshJSONWebToken都继承了JSONWebTokenAPIView
  5. urlpatterns = [
  6. path('login/', ObtainJSONWebToken.as_view()),
  7. ]
  8. # 使用post请求带着用户和密码去访问http://127.0.0.1:8000/login/,就会得到token

2、视图访问 JWT认证类

但是 第三方JWT的认证必须要在请求头中添加 Authorization 和对应的 JWT +token参数,才会进行认证,否则就不认证(不好用需要从新写)

  1. from rest_framework.views import APIView
  2. from rest_framework.response import Response
  3. from rest_framework_jwt.authentication import JSONWebTokenAuthentication
  4. class TestView(APIView):
  5. # 局部配置
  6. authentication_classes = [JSONWebTokenAuthentication]
  7. def get(self, request):
  8. return Response('认证测试')
  9. # 全局配置需要在settings.py配置
  10. REST_FRAMEWORK = {
  11. 'DEFAULT_AUTHENTICATION_CLASSES': [
  12. 'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
  13. ]
  14. }

自定义JWT认证类

由于第三方的 JWT认证必须要在请求中添加 Authorization字段才会认证,否则不认证直接通过,所以不使用它,自己写一个基于第三方JWT的认证类,这样请求头中没有Authorization字段,就会认证失败。

  1. # 由于使用的是基于第三方的认证,所有还是要继承它,并且使用一些它的方法,而且还要重写authenticate方法
  2. # app_auth.py
  3. from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication
  4. from rest_framework_jwt.utils import jwt_decode_handler
  5. from rest_framework import exceptions
  6. class TestAuth(BaseJSONWebTokenAuthentication):
  7. def authenticate(self, request):
  8. # 获取JWT的token值
  9. jwt_value = request.META.get('HTTP_AUTHORIZATION')
  10. try:
  11. # 认证
  12. payload = jwt_decode_handler(jwt_value)
  13. except Exception:
  14. raise exceptions.AuthenticationFailed('认证失败')
  15. # 获取用户对象
  16. user = self.authenticate_credentials(payload)
  17. return user, None
  18. # views.py
  19. # 局部使用
  20. from rest_framework.views import APIView
  21. from rest_framework.response import Response
  22. from app01.app_auth import TestAuth
  23. class TestView(APIView):
  24. # 局部配置
  25. authentication_classes = [TestAuth]
  26. def get(self, request):
  27. return Response('认证测试')
  28. # 全局配置需要在settings.py配置
  29. REST_FRAMEWORK = {
  30. 'DEFAULT_AUTHENTICATION_CLASSES': [
  31. 'app01.app_auth.TestAuth',
  32. ]
  33. }

二、手动签发token(多方式登录)

当用户使用用户名,手机号,邮箱等都可以登录

如:前端需要传的数据格式

  1. {
  2. "username":"xiaoyang/13313311333/133@qq.com",
  3. "password":"111111ys"
  4. }

url

  1. # post请求调用LoginView视图中的login函数
  2. re_path('login/', views.LoginView.as_view({'post': 'login'}))

views.py

  1. from rest_framework.viewsets import ViewSet
  2. from rest_framework.response import Response
  3. from app01.ser import UserModelSerializer
  4. class LoginView(ViewSet):
  5. def login(self, request):
  6. # 序列化一个类
  7. login_ser = UserModelSerializer(data=request.data, context={})
  8. # 验证,会调用序列化器中的钩子函数
  9. if login_ser.is_valid():
  10. token = login_ser.context.get('token')
  11. username = login_ser.context.get('username')
  12. # 验证成功返回用户名和token
  13. return Response({'username': username, 'token': token})
  14. else:
  15. # 验证失败返回错误信息
  16. return Response(login_ser.errors)

ser.py

  1. from rest_framework import serializers
  2. from rest_framework.exceptions import ValidationError
  3. from rest_framework_jwt.utils import jwt_encode_handler, jwt_payload_handler
  4. from app01.models import User
  5. import re
  6. class UserModelSerializer(serializers.ModelSerializer):
  7. # 重新覆盖username字段,数据库中它是唯一的(unique),post会认为是你自己保存数据,自己校验没过
  8. username = serializers.CharField(max_length=16)
  9. class Meta:
  10. model = User
  11. fields = ['username', 'password']
  12. # 全局钩子
  13. def validate(self, attrs):
  14. username = attrs.get('username')
  15. password = attrs.get('password')
  16. if re.match(r'^1[3-9]\d{9}', username):
  17. # 电话登录
  18. user = User.objects.filter(phone=username).first()
  19. elif re.match(r'.*@.*', username):
  20. # 邮箱登录
  21. user = User.objects.filter(email=username).first()
  22. else:
  23. # 用户名登录
  24. user = User.objects.filter(username=username).first()
  25. if user:
  26. # 校验密码,因为用的是auth模块,所以使用check_password
  27. user.check_password(password)
  28. payload = jwt_payload_handler(user) # 放入用户生成payload
  29. token = jwt_encode_handler(payload) # 放入payload生成token
  30. self.context['token'] = token
  31. self.context['username'] = user.username
  32. return attrs
  33. else:
  34. raise ValidationError('用户名或密码错误')

DRF之JWT认证的更多相关文章

  1. drf框架 - JWT认证插件

    JWT认证 JWT认证方式与其他认证方式对比: 优点 1) 服务器不要存储token,token交给每一个客户端自己存储,服务器压力小 2)服务器存储的是 签发和校验token 两段算法,签发认证的效 ...

  2. drf的JWT认证

    JWT认证(5星) token发展史 在用户注册或登录后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证.我们不再使用Session认证机制,而使用Json Web Token(本质就是tok ...

  3. drf框架中jwt认证,以及自定义jwt认证

    0909自我总结 drf框架中jwt 一.模块的安装 官方:http://getblimp.github.io/django-rest-framework-jwt/ 他是个第三方的开源项目 安装:pi ...

  4. drf组件之jwt认证

    drf组件之jwt认证模块 一.认证规则 全称:json web token 解释:加密字符串的原始数据是json,后台产生,通过web传输给前台存储 格式:三段式 - 头.载荷.签名 - 头和载荷才 ...

  5. DRF框架(七) ——三大认证组件之频率组件、jwt认证

    drf频率组件源码 1.APIView的dispatch方法的  self.initial(request,*args,**kwargs)  点进去 2.self.check_throttles(re ...

  6. DRF的JWT用户认证

    目录 DRF的JWT用户认证 JWT的认证规则 JWT的格式 JWT认证的流程 JWT模块的导入为 JWT的使用 DRF的JWT用户认证 从根本上来说,JWT是一种开放的标准(RFC 7519), 全 ...

  7. drf认证组件、权限组件、jwt认证、签发、jwt框架使用

    目录 一.注册接口 urls.py views.py serializers.py 二.登录接口 三.用户中心接口(权限校验) urls.py views.py serializers.py 四.图书 ...

  8. drf认证组件(介绍)、权限组件(介绍)、jwt认证、签发、jwt框架使用

    目录 一.注册接口 urls.py views.py serializers.py 二.登录接口 三.用户中心接口(权限校验) urls.py views.py serializers.py 四.图书 ...

  9. 9) drf JWT 认证 签发与校验token 多方式登陆 自定义认证规则反爬 admin密文显示

    一 .认证方法比较 1.认证规则图 django 前后端不分离 csrf认证 drf 前后端分离 禁用csrf 2. 认证规则演变图 数据库session认证:低效 缓存认证:高效 jwt认证:高效 ...

随机推荐

  1. Day029 JDK8中新日期和时间API (四)

    JDK8中新日期和时间API 其他的一些API ZoneId:该类中包含了所有的时区信息,一个时区的ID,如 Europe/Paris ZonedDateTime:一个在ISO-8601日历系统时区的 ...

  2. 在gin框架中使用JWT

    在gin框架中使用JWT JWT全称JSON Web Token是一种跨域认证解决方案,属于一个开放的标准,它规定了一种Token实现方式,目前多用于前后端分离项目和OAuth2.0业务场景下. 什么 ...

  3. Python保留指定位数的小数

    Python保留指定位数的小数 1 '%.2f' %f 方法(推荐) f = 1.23456 print('%.4f' % f) print('%.3f' % f) print('%.2f' % f) ...

  4. Camera噪声问题

    Camera噪声问题 Camera RGB 域的噪声 以上部分属于sensor processing,接下来的部分属于color.luminance processing. gamma gamma是在 ...

  5. 降维-基于RDD的API

    降维-基于RDD的API Singular value decomposition (SVD) Performance SVD Example Principal component analysis ...

  6. Python API vs C++ API of TensorRT

    Python API vs C++ API of TensorRT 本质上,C++ API和Python API应该在支持您的需求方面接近相同.pythonapi的主要优点是数据预处理和后处理都很容易 ...

  7. Java真的是白天鹅

    前言 我最近越来越真切的感受到,Java真的是白天鹅. 这真的是一种羡慕嫉妒恨的感受. 今天和一个Java技术Leader聊天,我告诉他敏捷开发是以人为本,他居然跟我说敏捷开发在行业内有规范,规范是死 ...

  8. 【python学习小知识】求绝对值和numpy和tensor的相互转换

    一.python求绝对值的三种方法 1.条件判断 2.内置函数abs() 3.内置模块 math.fabs 1.条件判段,判断大于0还是小于0,小于0则输出相反数即可 # 法1:使用条件判断求绝对值 ...

  9. vue3.0 props

    .orange { color: rgba(255, 165, 0, 1) } Vue3.0 props 1.你是否遇到了,引用props数据报错的问题? 在Vue3.0中,采用了proxy,让很多数 ...

  10. 为IHttpClientFactory添加动态命名配置

    某些时候我们需要为HttpClient动态配置一些东西, 例如证书等, 参考博问 如何使用IHttpClientFactory动态添加cer证书. 例如服务是一个回调服务, 而被回调方采用了自定义的h ...