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)中客户名称也将减少一个; 如果增加一个客户信息,…...
使用 C++ 模拟 ShaderLanguage 的 swizzle
经常编写着色器的同学应该对 swizzle(重排)语法非常熟悉,方便又灵活,可以说是用过一次便回味无穷。 代码 vec4 color vec4(1.0, 0.5, 0.0, 1.0); vec3 rgb color.rgb; // { 1.0, 0.5, 0.0 } vec2 xy color.xy; …...
线程与进程的区别与联系:操作系统入门详解(含 Python 示例)
、先搞懂:进程与线程到底是什么?(通俗类比官方定义) 1.1 生活化类比:快速建立认知 如果把计算机的操作系统比作一个大型工厂: 进程:就是工厂里的一个个独立车间。每个车间有自己专属的生产资…...
OpenClaw性能调优:ollama-QwQ-32B模型批处理与缓存机制实战
OpenClaw性能调优:ollama-QwQ-32B模型批处理与缓存机制实战 1. 为什么需要性能调优? 上周我遇到了一个棘手的问题:需要让OpenClaw自动处理100份PDF文档的摘要生成任务。本以为只是简单的批量调用模型,结果发现处理速度慢得惊人—…...
终极指南:ComfyUI-LTXVideo深度解析与高效视频生成实战
终极指南:ComfyUI-LTXVideo深度解析与高效视频生成实战 【免费下载链接】ComfyUI-LTXVideo LTX-Video Support for ComfyUI 项目地址: https://gitcode.com/GitHub_Trending/co/ComfyUI-LTXVideo ComfyUI-LTXVideo 是专为LTX-2视频生成模型设计的强大ComfyUI…...
FPGA设计中的组合逻辑环:为什么你的Verilog代码会引发警告?
FPGA设计中的组合逻辑环:为什么你的Verilog代码会引发警告? 在数字电路设计的浩瀚海洋中,组合逻辑环(Combinational Loop)就像是一个潜伏的暗礁,看似无害却可能让你的整个设计"触礁沉没"。作为一…...
GME-Qwen2-VL-2B-Instruct效果扩展:多风格艺术画作的理解与情感分析展示
GME-Qwen2-VL-2B-Instruct效果扩展:多风格艺术画作的理解与情感分析展示 最近在玩一个挺有意思的视觉语言模型,叫GME-Qwen2-VL-2B-Instruct。它个头不大,但能力挺让人意外。我突发奇想,把它当成了一个“数字艺术评论员”…...
CentOS8网络管理大变革:从network.service到NetworkManager的全面解析
CentOS8网络管理架构深度解析:从传统命令到NetworkManager的进化之路 如果你是一位长期使用CentOS的系统管理员,最近升级到CentOS8后可能会遇到一个令人困惑的问题:当你习惯性地输入systemctl restart network命令时,系统却无情地…...
GEE实战指南:Sentinel-2多光谱植被指数批量计算与优化
1. 为什么需要植被指数? 植被指数是遥感领域用来量化植被生长状态的核心指标。简单来说,就像医生用体温计判断病人是否发烧一样,我们可以通过卫星数据计算出的植被指数,快速了解一片区域的植被健康状况。Sentinel-2卫星提供的多光…...
Obsidian Copilot 深度解析:构建知识管理中的智能代理系统
Obsidian Copilot 深度解析:构建知识管理中的智能代理系统 【免费下载链接】obsidian-copilot A ChatGPT Copilot in Obsidian 项目地址: https://gitcode.com/gh_mirrors/ob/obsidian-copilot 在知识管理工具日益同质化的今天,Obsidian Copilot …...
APKMirror客户端:安卓应用安全下载与管理的革新方案
APKMirror客户端:安卓应用安全下载与管理的革新方案 【免费下载链接】APKMirror 项目地址: https://gitcode.com/gh_mirrors/ap/APKMirror 在安卓应用获取的过程中,用户常常面临两难选择:官方应用商店的更新滞后与第三方平台的安全隐…...
