一、JWT认证

JWT构成

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

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

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

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

过期时间配置:

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

校验过程

  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

# 首先创建超级用户 》》python manage.py createsuperuser

from rest_framework_jwt.views import ObtainJSONWebToken, VerifyJSONWebToken, RefreshJSONWebToken

# 基类:JSONWebTokenAPIView 继承了APIView
# ObtainJSONWebToken,VerifyJSONWebToken,RefreshJSONWebToken都继承了JSONWebTokenAPIView urlpatterns = [
path('login/', ObtainJSONWebToken.as_view()),
] # 使用post请求带着用户和密码去访问http://127.0.0.1:8000/login/,就会得到token

2、视图访问 JWT认证类

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

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework_jwt.authentication import JSONWebTokenAuthentication class TestView(APIView): # 局部配置
authentication_classes = [JSONWebTokenAuthentication] def get(self, request):
return Response('认证测试') # 全局配置需要在settings.py配置
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
]
}

自定义JWT认证类

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

# 由于使用的是基于第三方的认证,所有还是要继承它,并且使用一些它的方法,而且还要重写authenticate方法
# app_auth.py
from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication
from rest_framework_jwt.utils import jwt_decode_handler
from rest_framework import exceptions class TestAuth(BaseJSONWebTokenAuthentication): def authenticate(self, request):
# 获取JWT的token值
jwt_value = request.META.get('HTTP_AUTHORIZATION') try:
# 认证
payload = jwt_decode_handler(jwt_value)
except Exception:
raise exceptions.AuthenticationFailed('认证失败') # 获取用户对象
user = self.authenticate_credentials(payload)
return user, None # views.py
# 局部使用
from rest_framework.views import APIView
from rest_framework.response import Response
from app01.app_auth import TestAuth class TestView(APIView):
# 局部配置
authentication_classes = [TestAuth] def get(self, request):
return Response('认证测试') # 全局配置需要在settings.py配置
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'app01.app_auth.TestAuth',
]
}

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

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

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

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

url

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

views.py

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

ser.py

from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from rest_framework_jwt.utils import jwt_encode_handler, jwt_payload_handler
from app01.models import User
import re class UserModelSerializer(serializers.ModelSerializer):
# 重新覆盖username字段,数据库中它是唯一的(unique),post会认为是你自己保存数据,自己校验没过
username = serializers.CharField(max_length=16) class Meta:
model = User
fields = ['username', 'password'] # 全局钩子
def validate(self, attrs):
username = attrs.get('username')
password = attrs.get('password') if re.match(r'^1[3-9]\d{9}', username):
# 电话登录
user = User.objects.filter(phone=username).first()
elif re.match(r'.*@.*', username):
# 邮箱登录
user = User.objects.filter(email=username).first()
else:
# 用户名登录
user = User.objects.filter(username=username).first() if user:
# 校验密码,因为用的是auth模块,所以使用check_password
user.check_password(password) payload = jwt_payload_handler(user) # 放入用户生成payload
token = jwt_encode_handler(payload) # 放入payload生成token self.context['token'] = token
self.context['username'] = user.username return attrs
else:
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. linux ( crontab 定时任务命令)

    linux ( crontab 定时任务命令)    crontab 定时任务命令 linux 系统则是由 cron (crond) 这个系统服务来控制的.Linux 系统上面原本就有非常多的计划性工 ...

  2. redis主从架构宕机问题手动解决

    1    主机宕机 1.  设置端口6379是主机,端口6380是从机,全部都正常启动 2.  验证在6379写入数据,在6380也能得到数据 3.  现在将6379主机停掉,模拟主机宕机 4.  由 ...

  3. Camera Calibration 相机标定

    Camera Calibration 相机标定 一.相机标定方法 在opencv中提供了一组函数用于实现相机的标定,标定返回的值包括:相机内参矩阵(fx fy xc yc).相机外参矩阵(R t)以及 ...

  4. PyTorch 数据并行处理

    PyTorch 数据并行处理 可选择:数据并行处理(文末有完整代码下载) 本文将学习如何用 DataParallel 来使用多 GPU. 通过 PyTorch 使用多个 GPU 非常简单.可以将模型放 ...

  5. Hashing散列注意事项

    Hashing散列注意事项 Numba支持内置功能hash(),只需__hash__()在提供的参数上调用成员函数即可 .这使得添加对新类型的哈希支持变得微不足道,这是因为扩展APIoverload_ ...

  6. 嵌入式Linux设备驱动程序:发现硬件配置

    嵌入式Linux设备驱动程序:发现硬件配置 Embedded Linux device drivers: Discovering the hardware configuration Interfac ...

  7. Docker-compose搭建ELK环境并同步MS SQL Server数据

    前言 本文作为学习记录,供大家参考:一次使用阿里云(Aliyun)1核2G centos7.5 云主机搭建Docker下的ELK环境,并导入MS SQL Server的商品数据以供Kibana展示的配 ...

  8. 痞子衡嵌入式:嵌入式里串口(UART)自动波特率识别程序设计与实现

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是嵌入式里串口(UART)自动波特率识别程序设计与实现. 串口(UART)是嵌入式里最基础最常用也最简单的一种通讯(数据传输)方式,可以说 ...

  9. [源码解析] 深度学习分布式训练框架 horovod (3) --- Horovodrun背后做了什么

    [源码解析] 深度学习分布式训练框架 horovod (3) --- Horovodrun背后做了什么 目录 [源码解析] 深度学习分布式训练框架 horovod (3) --- Horovodrun ...

  10. 【VBA】模块更新方法

    删除模块,重新导入 1 Sub 更新模块() 2 With ThisWorkbook.VBProject 3 .VBComponents.Remove .VBComponents("模块1& ...