Django初窥门径-oauth登录认证
引言
在现代Web应用程序中,用户身份验证和授权是至关重要的组成部分。Django,一个流行的Python Web框架,为用户身份验证提供了内置支持。本文将探讨如何创建和注册Django应用,自定义身份验证服务,配置AUTHENTICATION_BACKENDS,创建视图以及如何使用API视图获取当前登录用户的信息。
Django框架和OAuth身份验证
Django是一个高度可定制的Web框架,它提供了强大的工具和库,用于快速构建Web应用程序。OAuth是一种开放标准,用于安全地授权访问资源,通常用于身份验证。结合Django和OAuth,您可以构建安全和可扩展的用户身份验证和授权系统。
创建应用和注册应用
要创建一个Django应用,您可以使用以下命令:
python manage.py startapp oauth
然后,在项目的settings.py文件中,将应用注册到INSTALLED_APPS列表中,如下所示:
INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','rest_framework','drf_yasg2','django_filters','account.apps.AccountConfig','oauth'
]
身份验证服务
创建自定义身份验证服务
#!/usr/bin/python
# -*- coding: utf-8 -*-
from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
from django.core.cache import cache
from django.db.models import Q
from django.http import Http404
from django.shortcuts import get_object_or_404
from django.utils import timezone
from rest_framework import exceptions
from rest_framework.authentication import TokenAuthentication as BaseTokenAuthenticationUser = get_user_model()def get_ip(request):"""获取当前请求ip:param request: 当前请求上下文:return: ip地址"""x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')if x_forwarded_for:ip = x_forwarded_for.split(',')[0]else:ip = request.META.get('REMOTE_ADDR')return ipclass EmailOrUsernameModelBackend(ModelBackend):"""自定义用户验证允许用户使用用户名或者邮箱登录允许使用密码或者邮箱验证码校验"""def authenticate(self, request, username=None, password=None, login_type='account', **kwargs):try:user = User.objects.get(Q(username=username) | Q(email=username), is_active=True)if login_type == 'account' and user.check_password(password):user.last_login = timezone.now()user.last_login_ip = get_ip(request)user.save()return userelse:# 邮箱验证码校验code = cache.get('account:email:{0}:login:code'.format(user.email))if password == code:return userreturn Noneexcept User.DoesNotExist:return Noneclass TokenAuthentication(BaseTokenAuthentication):"""token认证"""keyword = 'bearer'def authenticate_credentials(self, key):token_user_cache_key = f'oauth:token:{key}:user:id'if cache.ttl(token_user_cache_key) == 0:raise exceptions.AuthenticationFailed('token无效')try:user_id = cache.get(token_user_cache_key)user_token_cache_key = f'oauth:user:id:{user_id}:token'if cache.ttl(user_token_cache_key) != 0 and cache.get(user_token_cache_key) == key:user = get_object_or_404(User, id=user_id, is_active=True)return user, keyraise exceptions.AuthenticationFailed('token错误')except Http404:raise exceptions.AuthenticationFailed('token无效')
在自定义身份验证服务中,我们创建了EmailOrUsernameModelBackend和TokenAuthentication类,以改进用户身份验证和安全性。EmailOrUsernameModelBackend允许用户使用用户名或邮箱登录,还支持邮箱验证码校验。TokenAuthentication用于验证用户的令牌。这些自定义服务增强了用户身份验证的功能和灵活性。
配置`AUTHENTICATION_BACKENDS
为了使用我们的自定义身份验证服务,我们需要配置AUTHENTICATION_BACKENDS,如下所示:
AUTHENTICATION_BACKENDS = ('oauth.authentication.EmailOrUsernameModelBackend',
)
创建视图
登录表单
#!/usr/bin/python
# -*- coding: utf-8 -*-
from django.contrib.auth.forms import AuthenticationForm
from django.forms import widgetsclass LoginForm(AuthenticationForm):"""登录表单"""def __init__(self, *args, **kwargs):super(LoginForm, self).__init__(*args, **kwargs)self.fields['username'].widget = widgets.TextInput(attrs={'id': 'username','class': 'form-control','aria-errormessage': 'usernameError','placeholder': '用户名'})self.fields['password'].widget = widgets.PasswordInput(attrs={'id': 'password','class': 'form-control','aria-errormessage': 'passwordError','placeholder': '密码'})
登录视图
class LoginView(FormView):"""登录视图"""form_class = LoginFormtemplate_name = 'oauth/login.html'@method_decorator(sensitive_post_parameters('password'))@method_decorator(csrf_protect)@method_decorator(never_cache)def dispatch(self, request, *args, **kwargs):return super(LoginView, self).dispatch(request, *args, **kwargs)def get_context_data(self, **kwargs):kwargs['redirect_to'] = get_redirect_uri(self.request)return super(LoginView, self).get_context_data(**kwargs)def post(self, request, *args, **kwargs):form = LoginForm(data=self.request.POST, request=self.request)if form.is_valid():auth.login(self.request, form.get_user())return super(LoginView, self).form_valid(form)return self.render_to_response({'form': form})def get_success_url(self):authorize_uri = reverse('authorize', request=self.request, kwargs={'authorize_type': 'account'})data = parse.urlencode({'response_type': 'token','redirect_uri': get_redirect_uri(self.request)})return f'{authorize_uri}?{data}'
注销视图
class LogoutView(RedirectView):"""退出登录"""@method_decorator(never_cache)def dispatch(self, request, *args, **kwargs):return super(LogoutView, self).dispatch(request, *args, **kwargs)def get(self, request, *args, **kwargs):user = request.useruser_token_cache_key = f'oauth:user:id:{user.id}:token'if cache.ttl(user_token_cache_key) != 0:token = cache.get(user_token_cache_key)cache.delete(user_token_cache_key)token_user_cache_key = f'oauth:token:{token}:user:id'if cache.ttl(token_user_cache_key) != 0:cache.delete(token_user_cache_key)logout(request)return super(LogoutView, self).get(request, *args, **kwargs)def get_redirect_url(self, *args, **kwargs):return get_redirect_uri(self.request)
用户授权视图
class AuthorizeView(RedirectView):"""用户授权"""@method_decorator(never_cache)def dispatch(self, request, *args, **kwargs):return super(AuthorizeView, self).dispatch(request, *args, **kwargs)def get_redirect_url(self, authorize_type, *args, **kwargs):request = self.requestuser = request.usertoken = Noneif authorize_type == 'account':if user.is_authenticated:token = generate_token()token_user_cache_key = f'oauth:token:{token}:user:id'user_token_cache_key = f'oauth:user:id:{user.id}:token'cache.set(token_user_cache_key, user.id, timeout=60 * 60 * 24)cache.set(user_token_cache_key, token, timeout=None)if token:data = parse.urlencode({'access_token': token,'token_type': 'bearer'})return f'{get_redirect_uri(request)}#{data}'return reverse('login', request=request)
我们创建了登录表单、登录视图、注销视图和用户授权视图。这些视图提供了用户身份验证和授权的功能。登录表单具有定制的字段,登录视图支持密码和邮箱验证码校验,而注销视图用于用户退出登录。用户授权视图负责用户身份验证后的授权操作。
API视图获取当前登录用户信息
定义用户模型序列化器
#!/usr/bin/python
# -*- coding: utf-8 -*-
from django.contrib.auth import get_user_model
from rest_framework import serializersUser = get_user_model()class UserSerializer(serializers.ModelSerializer):"""用户模型列化"""class Meta:model = Userexclude = ('password',)read_only_fields = ('avatar', 'last_login', 'last_login_ip', 'active')
定义视图
from django.shortcuts import render
from rest_framework import permissions
from rest_framework.generics import GenericAPIViewfrom CodeVoyager import mixins
from .serializers import UserSerializer# Create your views here.
class UserProfileAPIView(mixins.UpdateModelMixin, mixins.RetrieveModelMixin, GenericAPIView):"""用户信息api视图"""permission_classes = (permissions.IsAuthenticated,)serializer_class = UserSerializerdef get_object(self):user = self.request.userif user.is_anonymous or not user.is_authenticated:return Nonereturn self.request.userdef get(self, request, *args, **kwargs):return self.retrieve(request, *args, **kwargs)def put(self, request, *args, **kwargs):return self.update(request, *args, **kwargs)def patch(self, request, *args, **kwargs):return self.partial_update(request, *args, **kwargs)
我们定义了API视图,用于获取当前登录用户的信息。这对于构建需要用户信息的应用程序非常有用。我们还提供了用户信息的序列化过程,以及如何使用API视图来检索和更新用户信息。
使用swagger测试

结语
用户身份验证和授权是任何Web应用程序的核心。通过结合Django和OAuth,您可以创建一个安全和可扩展的身份验证系统,满足不同项目的需求。希望本文能帮助您更好地理解和应用这些概念,从而构建强大的Web应用程序。
拓展和学习
如果您想进一步了解Django身份验证和OAuth,以下是一些有用的资源:
- Django官方文档: 深入了解Django框架的官方文档。
- OAuth 2.0官方文档: 了解OAuth 2.0标准的官方文档。
- Django REST framework: 用于构建RESTful API的Django库的官方网站。
通过这些资源,您可以进一步扩展您的知识和技能,以构建更复杂和安全的Web应用程序。
相关文章:
Django初窥门径-oauth登录认证
引言 在现代Web应用程序中,用户身份验证和授权是至关重要的组成部分。Django,一个流行的Python Web框架,为用户身份验证提供了内置支持。本文将探讨如何创建和注册Django应用,自定义身份验证服务,配置AUTHENTICATION_…...
数学到底在哪里支撑着编程?
数学到底在哪里支撑着编程? 除了少数算法等明显相关情况外,说点日常的。 编程是个极度依赖逻辑的领域,逻辑严谨性好,你的编程工作会顺畅很多一-绝大多 数的bug都是最近很多小伙伴找我,说想要一些嵌入式的资料&#x…...
Python模块ADB的, 已经 pyadb
Python模块ADB的使用指南_笔记大全_设计学院 (python100.com) pip install adb Python 调用ADB_python 调用adb命令_实相实相的博客-CSDN博客 Python ADB.shell_command Examples, pyadb.ADB.shell_command Python Examples - HotExamples Gitee 极速下载/PyADB - 码云 - 开…...
猫头虎分享从Python到JavaScript传参数:多面手的数据传递术
🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…...
注解汇总:Spring 常用的注解
前言 本栏目的内容已经讲完了,本案例将把案例中所有讲到的注解都汇总起来,方便日后的学习需要用到的时候能够快速的找到相应的注解。本案例将结合小案例一起做汇总,也想丹玉是再复习一遍讲过用过的注解。 一、注解汇总 1、Component Reposi…...
合肥工业大学操作系统实验5
✅作者简介:CSDN内容合伙人、信息安全专业在校大学生🏆 🔥系列专栏 :hfut实验课设 📃新人博主 :欢迎点赞收藏关注,会回访! 💬舞台再大,你不上台,永远是个观众。平台再好,你不参与,永远是局外人。能力再大,你不行动,只能看别人成功!没有人会关心你付出过多少…...
基于SpringBoot+Vue的点餐管理系统
基于springbootvue的点餐平台网站系统的设计与实现~ 开发语言:Java数据库:MySQL技术:SpringBootMyBatisVue工具:IDEA/Ecilpse、Navicat、Maven 系统展示 菜品详情 个人中心 订单 管理员界面 菜品管理 摘要 点餐管理系统是一种用…...
C# 继承,抽象,接口,泛型约束,扩展方法
文章目录 前言模拟需求场景模拟重复性高的需求初始类结构继承优化抽象类 需求1:打印CreateTime方法1:使用重载方法2:基类函数方法3:泛型约束方法3.1:普通泛型方法方法3.2:高级泛型约束,扩展方法…...
mysql的备份和恢复
备份:完全备份 增量备份 完全备份:将整个数据库完整的进行备份 增量备份:在完全备份的基础之上,对后续新增的内容进行备份 备份的需求 1、在生产环境中,数据的安全至关重要,任何数据的都可能产生非常严重…...
【机器学习3】有监督学习经典分类算法
1 支持向量机 在现实世界的机器学习领域, SVM涵盖了各个方面的知识, 也是面试题目中常见的基础模型。 SVM的分类结果仅依赖于支持向量,对于任意线性可分的两组点,它 们在SVM分类的超平面上的投影都是线性不可分的。 2逻辑回归 …...
lv11 嵌入式开发 计算机硬件基础 1
目录 1 导学 1.1回顾及导学 1.2 嵌入式系统分层 1.3 linux底层开发 2 ARM体系结构与接口技术课程导学 3 计算机基础 3.1 计算机的进制 3.2 计算机组成 3.3 总线 4 多级存储结构与地址空间 4.1 多级存储概念 4.2 地址空间 5 CPU工作原理 6 练习 1 导学 1.1回顾及导…...
【Linux】vim
文章目录 一、vim是什么?二 、命令模式三、插入模式四、底行模式五、vim配置 一、vim是什么? Vim是一个强大的文本编辑器,它是Vi的增强版,支持多种语法高亮、插件扩展、多模式操作等功能。Vim有三种基本的工作模式:命…...
cstring函数
string 1.char str[]类型 fgets(s,10000,stdin) cin.getline(cin,10000) strlen(str) sizeof 求静态数组长度 2.string类型 getline(cin,a) cin.getline(cin,10000) str.lenth() str.size() cin 遇到空格就停止 3.gets 函数 char str[20]; gets(str); 4.puts 函…...
【owt】p2p client mfc 工程梳理
1年前构建的,已经搞不清楚了。所以梳理下,争取能用较新的webrtc版本做测试。最早肯定用这个测试跑通过 【owt】p2p Signaling Server 运行、与OWT-P2P-MFC 交互过程及信令分析官方的mfc客户端 估计是构造了多个不同的webrc版本的客户端...
pandas教程:Hierarchical Indexing 分层索引、排序和统计
文章目录 Chapter 8 Data Wrangling: Join, Combine, and Reshape(数据加工:加入, 结合, 变型)8.1 Hierarchical Indexing(分层索引)1 Reordering and Sorting Levels(重排序和层级排序)2 Summa…...
Redis 扩展 RedisBloom 插件,解决缓存击穿、穿透
文章目录 一、概述二、编译准备2.1 升级 make2.2 安装 Python3 三、编译 RedisBloom四、测试 RedisBloom五、应用场景5.1 缓存击穿5.2 缓存穿透5.3 原理总结 六、存在的问题 如果您对Redis的了解不够深入请关注本栏目,本栏目包括Redis安装,Redis配置文件…...
VBA技术资料MF80:选择文件及文件夹
我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。我的教程一共九套,分为初级、中级、高级三大部分。是对VBA的系统讲解,从简单的入门,到…...
网络层:控制平面
路由选择算法 路由选择算法就是为了在端到端的数据传输中,选择路径上路由器的最好的路径。通常,一条好的路径指具有最低开销的路径。最低开销路径是指源和目的地之间具有最低开销的一条路。 根据集中式还是分散式来划分 集中式路由选择算法:…...
Ubuntu 系统内核 kernel panic
Ubuntu 系统内核 kernel panic 不能进入系统:报错end kernel panic -not syncing: attemped to kill init! exit code 0x00000100 系统启动的时候,按下‘e’键进入grub编辑界面,编辑grub菜单,选择“kernel /vmlinuz-XXXXro root…...
【flink】RowData copy/clone方式
说明:一般用户常用的是GenericRowData。flink内部则多使用BinaryRowData。 方法一、循环解决(不推荐): 代码较为复杂需要根据RowType获取到内部fields的logicalType,再使用RowData.createFieldGetter方法创建fieldGetters。 public static …...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
