一、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. Python for循环 - Python零基础入门教程

    目录 一.for 循环语法 二.for 循环实战 三.重点总结 四.猜你喜欢 零基础 Python 学习路线推荐 : Python 学习目录 >> Python 基础入门 在 Python ...

  2. PHP转JAVA开发30分钟实战攻略

    服务端开发中,有很多知识是相通的,例如mysql,redis,http协议等. 基于这些基础,在编程语言上的转变并不困难. 本文主要从下面几点出发,讲述如何快速从php开发转为java开发: 使用框架 ...

  3. 第三方跨平台进程和系统监控库gopsutil

    gopsutil psutil是一个跨平台进程和系统监控的Python库,而gopsutil是其Go语言版本的实现.本文介绍了它的基本使用. Go语言部署简单.性能好的特点非常适合做一些诸如采集系统信 ...

  4. Go语言的函数02---参数

    package main import "fmt" /* 常量,变量,函数---源代码的成员 给成员命名的字符称之为[标识符] 合法的标识符有:大小写字母,数字,下划线 命名时不能 ...

  5. noip模拟5[string·matrix·big·所驼门王的宝藏]

    怎么说呢这一场考得还算可以呢 拿了120pts,主要是最后一个题灵光开窍,想起来是tarjan,然后勉勉强强拿了40pts,本来是可以拿满分的,害 没事考完了就要反思 这场考试我心态超好,从第一个题开 ...

  6. CVD和ALD薄膜沉积技术应用领域

    CVD和ALD薄膜沉积技术应用领域 显示 用于OLED.QD-OLED.甚至未来QLED的薄膜封装,通过有机/无机叠层结构的保护,水汽渗透率WVTR可降至10-5g/m2/day,保证OLED或者量子 ...

  7. 三维视觉惯性SLAM的有效Schmidt-EKF

    三维视觉惯性SLAM的有效Schmidt-EKF An Efficient Schmidt-EKF for 3D Visual-Inertial SLAM 论文地址: http://openaccess ...

  8. 用NVIDIA Tensor Cores和TensorFlow 2加速医学图像分割

    用NVIDIA Tensor Cores和TensorFlow 2加速医学图像分割 Accelerating Medical Image Segmentation with NVIDIA Tensor ...

  9. Kaggle上的犬种识别(ImageNet Dogs)

    Kaggle上的犬种识别(ImageNet Dogs) Dog Breed Identification (ImageNet Dogs) on Kaggle 在本节中,将解决在Kaggle竞赛中的犬种 ...

  10. 什么是阻塞、非阻塞、同步和异步以及IO模型

    首先先看如下几个问题,或者说我们经常会遇到的问题. 阻塞是否等于同步?非阻塞是否等于异步?同步一定是阻塞的么?异步一定是非阻塞的么?要把这四个概念讲明白,先从一顿简餐说起.假设你要做一顿便饭:烧土豆: ...