Django的Rest framework搭建自定义授权登录
系列文章目录
提示:阅读本章之前,请先阅读目录
文章目录
- 系列文章目录
- 一、前言
- User模型
- User的views
- User的serializers
- utils的md5加密
- 自定义认证方法
- 配置路由
- 总路由
- 分路由
- rest的配置
一、前言
之前的文章有写过通过jwt认证的文章,今天这一篇是通过自定义用户认证的;
使用场景:有些API需要用户登录成功之后,才能访问;有些无需登录就能访问
解决方法:创建两张表,一张用户表,一张token表,保存用户登录成功后生产的token;
然后需要认证的视图,前台每次请求需要在请求头中携带token,后端然后对token进行验证
缺点:每个用户登录一次就需要生成一条token记录保存在数据库里,当用户量大的时候,就会增加后台服务器压力!
User模型
class="language-python">from django.contrib.auth.hashers import make_password, check_password
from django.db import models# Create your models here.
class User(models.Model):"""用户模型类"""username = models.CharField(max_length=32,verbose_name='用户名')password = models.CharField(max_length=64,verbose_name='密码')mobile = models.CharField(max_length=11,unique=True,verbose_name='手机号')class Meta:db_table = 'user'verbose_name = "用户信息表"verbose_name_plural = verbose_namedef __str__(self):return self.usernamedef set_password(self,password):self.password = make_password(password)return Nonedef check_pwd(self,password):return check_password(self.password,password)class UserToken(models.Model):"""用户token表"""user = models.OneToOneField(User) # 与用户一对一关系token = models.CharField(max_length=64,verbose_name='token')class Meta:db_table = 'token'verbose_name = 'token表'verbose_name_plural = verbose_name
User的views
from django.shortcuts import render# Create your views here.
from rest_framework.generics import CreateAPIView, ListAPIView
from rest_framework.response import Response
from rest_framework.views import APIViewfrom .utils import md5
from . import models
from . import serclass UserLogin(APIView):'用户登录视图类'authentication_classes = []# 登录不需要认证def post(self,request):username = request.POST.get('username').strip()pwd = request.POST.get('password').strip()if not all([username,pwd]):return Response({'info':'参数不完整','code':400})user = models.User.objects.get(username=username)user.check_pwd(pwd)# 登录成功后生成tokentoken =md5(username)models.UserToken.objects.update_or_create(user=user,defaults={'token':token})res = {'info':'success','token':token,'code':200}res['data'] = ser.UserInfoSer(user).datareturn Response(res)class UserRegister(CreateAPIView):"""用户注册视图"""authentication_classes = []# 用户注册不需要认证serializer_class = ser.CreateUserSerclass UserInfoList(ListAPIView):"""用户详情页视图"""serializer_class = ser.UserInfoSerqueryset = models.User.objects.all()
User的serializers
class="language-python">from rest_framework import serializersfrom . import modelsclass CreateUserSer(serializers.ModelSerializer):"""新增用户序列化器"""password2 = serializers.CharField(max_length=64,write_only=True)mobile = serializers.CharField(max_length=11,min_length=11,write_only=True)def validate(self, attrs):password = attrs['password']password2 = attrs['password2']if password != password2:raise serializers.ValidationError('两次密码不一致,请重新输入!')return attrsdef validate_mobile(self,value):import reif not re.match(r'1[3-9]\d{9}',value):raise serializers.ValidationError('手机号格式不正确请重新输入!')return valuedef create(self, validated_data):del validated_data['password2']user = super().create(validated_data)user.set_password(validated_data['password'])user.save()return userclass Meta:model = models.Userfields = '__all__'class UserInfoSer(serializers.ModelSerializer):"""用户详情信息序列化器"""class Meta:model = models.Userfields = ('id','username','mobile')
utils的md5加密
import hashlib
import timedef md5(user):"""md5 加密token"""ctime = str(time.time())m = hashlib.md5(bytes(user, encoding='utf-8'))m.update(bytes(ctime, encoding='utf-8'))return m.hexdigest()
自定义认证方法
class Authtication(BaseAuthentication):def authenticate(self, request):try:token = request.META.get('HTTP_AUTHORIZATION', None)except:raise exceptions.AuthenticationFailed('用户认证失败')if token is None:raise exceptions.AuthenticationFailed('未提供认证信息')token = token.split(' ')[1]token_query = models.UserToken.objects.filter(token=token)if not token_query:raise exceptions.AuthenticationFailed('无效的token')# 返回(当前登录对象,token)return token_query.first().user, token_query.first()def authenticate_header(self, request):return 'Basic realm="user"'def authenticate_failed_response(self, exc):msg = str(exc)return Response({'msg': msg}, status=status.HTTP_401_UNAUTHORIZED)
配置路由
REST_FRAMEWORK = {# 全局使用的认证类"DEFAULT_AUTHENTICATION_CLASSES": ['users.auth.Authtication', ],"UNAUTHENTICATED_USER": None,"UNAUTHENTICATED_TOKEN": None,"DEFAULT_RENDERER_CLASSES": ['rest_framework.renderers.JSONRenderer','rest_framework.renderers.BrowsableAPIRenderer',]
}
总路由
urlpatterns = [url(r'^admin/', include(admin.site.urls)),url(r'^users/', include('users.urls')),
]
分路由
from django.conf.urls import include, url
from django.contrib import adminfrom . import views
urlpatterns = [url(r'^register/$',views.UserRegister.as_view()),url(r'^login/$',views.UserLogin.as_view()),url(r'^list/$',views.UserInfoList.as_view()),
]
rest的配置
REST_FRAMEWORK = {# 分页器'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',# 分页'PAGE_SIZE': 10,# 返回的时间格式'DATETIME_FORMAT': '%Y-%m-%d %H:%M:%S',# 返回的数据格式'DEFAULT_RENDER_CLASSES': ['rest_framework.renderers.JSONRenderer',],# 解析request.data'DEFAULT_PARSER_CLASSES': ['rest_framework.parsers.JSONParser','rest_framework.parsers.FormParser','rest_framework.parsers.MultiPartParser',],# 全局权限'DEFAULT_PERMISSION_CLASSES': ['common.auth.Authtication'],# 认证方式'DEFAULT_AUTHENTICATION_CLASSES': ['rest_framework.authentication.TokenAuthentication',],# 自定义抛出异常格式'EXCEPTION_HANDLER': 'common.custom_exception_handler.custom_exception_handler'
}
相关文章:
Django的Rest framework搭建自定义授权登录
系列文章目录 提示:阅读本章之前,请先阅读目录 文章目录 系列文章目录一、前言User模型User的viewsUser的serializersutils的md5加密自定义认证方法配置路由总路由分路由rest的配置 一、前言 之前的文章有写过通过jwt认证的文章,今天这一篇是…...
01 矩阵(力扣)多源广度优先搜索 JAVA
给定一个由 0 和 1 组成的矩阵 mat ,请输出一个大小相同的矩阵,其中每一个格子是 mat 中对应位置元素到最近的 0 的距离。 两个相邻元素间的距离为 1 。 输入:mat [[0,0,0],[0,1,0],[0,0,0]] 输出:[[0,0,0],[0,1,0],[0,0,0]] 输入…...
怎么绘制简爱思维导图?用这个工具绘制很简单
怎么绘制简爱思维导图?绘制思维导图是一项非常有用的技能,有助于梳理思路、整理知识、更好地理解和记忆信息。因此,无论你是学生、教师、工程师、项目经理或者只是想要更好地组织自己的想法,学会绘制思维导图都是非常有益的。下面…...
EC200U-CN学习(三)
EC200U系列内置丰富的网络协议,集成多个工业标准接口,并支持多种驱动和软件功能(适用于Windows 7/8/8.1/10、Linux和Android等操作系统下的USB驱动),极大地拓展了其在M2M领域的应用范围,如POS、POC、ETC、共…...
【windows】连接共享打印机提示:0x0000011B
【问题现象】 添加共享打印机的时候, 提示错误:0x0000011B。 【解决方法】 按winr键,在运行输入regedit 然后在注册表中找到路径: 计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print 打开后,在右侧…...
基于“RWEQ+”集成技术在土壤风蚀模拟与风蚀模数估算、变化归因分析中的实践应用及SCI论文撰写
【查看原文】基于“RWEQ”集成技术在土壤风蚀模拟与风蚀模数估算、变化归因分析中的实践应用及SCI论文撰写 土壤风蚀是一个全球性的环境问题。中国是世界上受土壤风蚀危害最严重的国家之一,土壤风蚀是中国干旱、半干旱及部分湿润地区土地荒漠化的首要过程。中国风…...
Flutter-基础Widget
Flutter页面-基础Widget 文章目录 Flutter页面-基础WidgetWidgetStateless WidgetStateful WidgetState生命周期 基础widget文本显示TextRichTextDefaultTextStyle 图片显示FlutterLogoIconImageIamge.assetImage.fileImage.networkImage.memory CircleAvatarFadeInImage 按钮R…...
【数据分析专栏之Python篇】二、Jupyer Notebook安装配置及基本使用
文章目录 前言一、Jupter Notebook是什么1.1 简介1.2 组成部分1.3 Jupyter Notebook的主要特点 二、为什么使用Jupyter Notebook?三、安装四、Jupyter Notebok配置4.1 基本配置4.2 配置开机自启与后台运行4.3 开启代码自动补全 五、两种键盘输入模式5.1 编辑模式5.2 命令模式5…...
ubuntu22.04 DNSSEC(加密DNS服务) configuration
/etx/systemd/resolved.conf是ubuntu下DNS解析服务配置文件,systemd为ubuntu下system and service配置目录 step 1——修改resolved.conf参数 管理员权限打开 /systemd/resolved.conf sudo nano /etc/systemd/resolved.conf修改如下: # This file i…...
Qt 第一讲
登录框设置 #include "zuoye.h" #include "ui_zuoye.h"Zuoye::Zuoye(QWidget *parent): QWidget(parent), ui(new Ui::Zuoye) {ui->setupUi(this);//界面this->resize(540,420); //设置尺寸this->setFixedSize(540,420);//固定尺寸this->setS…...
IDEA 使用 maven 搭建 spring mvc
1. 创建项目 1.1 创建成功之后配置 Spring MVC 1.2 勾选 Spring MVC 2.更改配置文件 2.1 更改web.xml配置 更改为 <servlet-mapping><servlet-name>dispatcher</servlet-name><url-pattern>/</url-pattern></servlet-mapping>2.2 dispat…...
Hi3536网络应用调优
目录 1. 为什么UDP接收或发送会丢包? 2. 使用 socket 接口时,如何正确工作在非阻塞模式下? 3. TOE 使能及使用注意事项 4. TOE 模式下使用 socket 接口时的注意事项 1. 为什么UDP接收或发送会丢包? 用户态应用程序在接收 UDP 数据时࿰…...
spring拦截器 与统一格式
目录 前言模拟拦截器拦截器的实现原理什么是动态代理? 什么是静态代理静态代理与动态代理的区别两种常用的动态代理方式基于接口的动态代理基于类的动态代理 JDK Proxy 与 CGlib的区别 其他 统⼀访问前缀添加统⼀异常处理统⼀数据返回格式 前言 之前博客讲述了 , 关于SpringA…...
leetcode 122. 买卖股票的最佳时机 II
2023.7.29 把整体利润拆分成每天的利润,将股票值想象成一个折线图,将所有上升的值相加即可。 代码: class Solution { public:int maxProfit(vector<int>& prices) {int ans 0;for(int i1; i<prices.size(); i){if(prices[i]-…...
代理模式:控制访问的设计模式
代理模式:控制访问的设计模式 什么是代理模式? 代理模式是一种常见的设计模式,它允许通过代理对象来控制对真实对象的访问。代理模式的主要目的是在不改变原始对象的情况下,提供额外的功能或控制访问。 为什么要使用代理模式&a…...
2020/7/30
Educational Codeforces Round 143 (Rated for Div. 2)\C_Tea_Tasting.cpp //题意:有n种茶,n个人,第i种茶有 a[i]的量,第i个人一次能喝 b[i], 第i个人从第i种茶开始往前喝,求每个人最多能喝多少茶。 //思路ÿ…...
图形编辑器开发:是否要像 Figma 一样上 wasm
大家好,我是前端西瓜哥。 wasm 拿来做 Web 端的图形编辑器貌似是不错的选择。 因为图形处理会有相当多无法利用到 WebGL GPU 加速的 CPU 密集的计算。比如对一条复杂贝塞尔曲线进行三角化,对多个图形进行复杂图形的布尔运算。 图形编辑器性能天花板 F…...
Linux学成之路(基础篇0(二十三)MySQL服务(主从MySQL服务和读写分离——补充)
目录 一、MySQL Replication概述 优点 异步复制(Asynchronous repication) 全同步复制(Fully synchronous replication) 半同步复制(Semisynchronous replication) 三、MySQL支持的复制 四、部署主从…...
spring启动流程 (6完结) springmvc启动流程
SpringMVC的启动入口在SpringServletContainerInitializer类,它是ServletContainerInitializer实现类(Servlet3.0新特性)。在实现方法中使用WebApplicationInitializer创建ApplicationContext、创建注册DispatcherServlet、初始化ApplicationContext等。 SpringMVC…...
设计模式-中介者模式在Java中使用示例-客户信息管理
场景 欲开发客户信息管理窗口界面,界面组件之间存在较为复杂的交互关系:如果删除一个客户, 要在客户列表(List)中删掉对应的项,客户选择组合框(ComboBox)中客户名称也将减少一个; 如果增加一个客户信息,…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
