一、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. conda 按照指定源下载python包

    conda 按照指定源下载python包 换成了国内的pip源就可以正常安装了,我使用的是:pip install xlrd -i http://pypi.douban.com/simple --tr ...

  2. TVM图优化与算子融合

    TVM图优化与算子融合 计算图的定义 Computational graphs: a common way to represent programs in deep learning framewo ...

  3. TensorRT 加速性能分析

    TensorRT 加速性能分析 Out-of-the-box GPU Performance 模型推理性能是什么意思?在为用户评估潜在的候选项时,不测量数据库查询和预筛选(例如决策树或手动逻辑)的贡献 ...

  4. C ++变量,文字和常量

    C ++变量,文字和常量 本文将借助示例来学习C ++中的变量,文字和常量. C ++变量 在编程中,变量是用于保存数据的容器(存储区). 为了指示存储区域,应该为每个变量赋予唯一的名称(标识符).例 ...

  5. CVPR2020:三维实例分割与目标检测

    CVPR2020:三维实例分割与目标检测 Joint 3D Instance Segmentation and Object Detection for Autonomous Driving 论文地址 ...

  6. 微调BERT:序列级和令牌级应用程序

    微调BERT:序列级和令牌级应用程序 Fine-Tuning BERT for Sequence-Level and Token-Level Applications 为自然语言处理应用程序设计了不同 ...

  7. JMeter定时器设置延迟与同步

    JMeter定时器一般用来设置延迟与同步.它的作用域和优先级如下: 定时器的优先级高于Sampler. 在同一作用域(比如控制器下)有多个定时器存在,每个定时器都会执行. 在某一Sampler节点下的 ...

  8. springboot——重定向解决刷新浏览器造成表单重复提交的问题(超详细)

    原因:造成表单重复提交的原因是当我们刷新浏览器的时候,浏览器会发送上一次提交的请求.由于上一次提交的请求方式为post,刷新浏览器就会重新发送这个post请求,造成表单重复提交. 解决办法: 将请求当 ...

  9. mybatis学习——多对一和一对多查询

    首先先来说明一下数据库,数据库有两张表student表和teacher表: student表如下: teacher表如下: 两张表的关系:多个学生关联一位老师(多对一) *其中tid是外键 需要sql ...

  10. Pytorch线性规划模型 学习笔记(一)

    Pytorch线性规划模型 学习笔记(一) Pytorch视频学习资料参考:<PyTorch深度学习实践>完结合集 Pytorch搭建神经网络的四大部分 1. 准备数据 Prepare d ...