一、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. CoSky 高性能 服务注册/发现 & 配置中心

    CoSky 基于 Redis 的服务治理平台(服务注册/发现 & 配置中心) Consul + Sky = CoSky CoSky 是一个轻量级.低成本的服务注册.服务发现. 配置服务 SDK ...

  2. 灵动微电子ARM Cortex M0 MM32F0010 Timer定时器中断定时功能的配置

    灵动微电子ARM Cortex M0 MM32F0010 Timer定时器中断定时功能的配置 目录: 1.Timer1高级定时器Timer3通用定时器Timer14基本定时器简介 2.Timer1高级 ...

  3. 写Bug时,需要注意的几点 02

    重构2-重新组织函数 重构的基本技巧--小步前进,频繁测试. 模式是你希望到达的目标,重构则是到达之路. 在单进程软件中,你永远不必操心多么频繁地调用某个函数,因为函数的调用成本很低.但在分布式软件中 ...

  4. kafka之一:kafka简介

    现在从事java开发的同学,不论是在面试过程中还是在日常的工作中,肯定会碰到消息队列的情况,市面上消息队列有很多:kafka.rocketMQ.rabbitMQ.zeroMQ等,从本篇博客起计划分享一 ...

  5. openresty 学习笔记一:环境安装

    openresty 学习笔记一:环境安装 openresty 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库.第三方模块以及大多数的依赖项.用于方便地搭 ...

  6. Go语言网络通信---TCP通信上传一个小文件

    server: package main import ( "fmt" "net" "os" ) func SHandleError(err ...

  7. checkbox,select,radio 选取值,设定值,回显值

    获取一组radio被选中项的值var item = $('input[@name=items][@checked]').val();获取select被选中项的文本var item = $(" ...

  8. MindSpore基准性能

    MindSpore基准性能 本文介绍MindSpore的基准性能.MindSpore网络定义可参考Model Zoo. 训练性能 ResNet 以上数据基于华为云AI开发平台ModelArts测试获得 ...

  9. TVM 架构设计

    TVM 架构设计 本文面向希望了解TVM体系结构和/或积极参与项目开发的开发人员. 主要内容如下: 示例编译流程概述了TVM将模型的高级概念转换为可部署模块的步骤. 逻辑架构组件部分描述逻辑组件.针对 ...

  10. pycham_编码格式设置,处理打印log乱码,处理读取配置文件报错

    一.打印日志乱码,处理设置如下: 二.配置文件读取方法因为gbk编码配置后需要同步修改 原报错信息: