Django_内置的用户认证系统

news2024/9/23 13:21:37

目录

一、用户对象

1. 创建用户

2. 修改密码

3. 用户验证

二、权限与授权

1. 默认权限

2. 用户组

3. 在代码中创建权限

4. 权限缓存

三、在视图中认证用户

1、登录用户

2、注销用户

3、用户登录的访问限制

3.1、原始的办法

3.2、函数视图使用login_required装饰器

3.3、类视图继承LoginRequiredMixin

4、用户权限的访问限制

5、认证视图

源码等资料获取方法


Django内置的用户认证系统,可用于处理用户账户、群组、许可和基于cookie的用户会话。

Django的认证系统包含了身份验证和权限管理两部分:

  • 身份验证用于核实某个用户是否合法
  • 权限管理决定一个合法用户具有哪些权限

Django的认证系统主要包括下面几个部分:

  • 用户
  • 许可
  • 可配置的密码哈希系统
  • 用于用户登录或者限制访问的表单和视图工具
  • 可插拔的后台系统

默认情况下,使用django-admin startproject命令后,认证相关的模块已经自动添加到settings文件内了,如果没有的话,请手动添加。

settings.INSTALLED_APPS配置项中添加:

  • 'django.contrib.auth': 包含认证框架的核心以及默认模型
  • 'django.contrib.contenttypes':内容类型系统,用于给模型关联许可

settings.MIDDLEWARE配置项中添加:

  • 'django.contrib.sessions.middleware.SessionMiddleware':通过请求管理会话
  • 'django.contrib.auth.middleware.AuthenticationMiddleware':将会话和用户关联

当配置正确后,运行manage.py migrate命令,创建用户认证系统相关的数据库表以及分配预定义的权限。

一、用户对象

用户对象是Django认证系统的核心,在Django的认证框架中只有一个用户模型也就是User模型,它位于django.contrib.auth.models

注意:本节内容叙述的所有功能,都是基于这个User模型的,和这个User模型没有任何关系的自定义用户模型是无法使用Django内置的认证系统功能的!

用户模型主要有下面几个字段:

  • username
  • password
  • email
  • first_name
  • last_name

1. 创建用户

可使用create_user()方法创建一个新用户:

PS D:\_git\djangodemo> python .\manage.py shell
Python 3.9.9 (tags/v3.9.9:ccb0e6a, Nov 15 2021, 18:08:50) [MSC v.1929 64 bit (AMD64)] on win32

>>> from django.contrib.auth.models import User                                      
>>> user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')
>>> user.last_name = 'Lennon'
>>> user.save()

查看auth_user表,可以看到创建的用户

2. 修改密码

Django默认会对密码进行加密,因此,不要在数据库中直接修改密码。

要修改密码,有两个办法:

  • 使用命令行: python manage.py changepassword username。如果不提供用户名,则会尝试修改当前系统用户的密码

  • 使用set_password()方法:
from django.contrib.auth.models import User
u = User.objects.get(username='john')
u.set_password('new_password')
u.save()

3. 用户验证

利用authenticate()方法,可对用户进行验证。该方法通常接收usernamepassword作为参数。要注意的是,认证的后端可能有好几个,有一项认证通过则返回一个User类对象,一项都没通过或者抛出了PermissionDenied异常,则返回一个None。例如:

>>> from django.contrib.auth import authenticate              
>>> user=authenticate(username='john',password='123456789')
>>> print(user)                                              
None
>>> user=authenticate(username='john',password='12345678') 
>>> print(user)                                              
john
>>> print(type(user))
<class 'django.contrib.auth.models.User'>
>>>

二、权限与授权

Django提供了一个简单的权限系统,并且已经用于它的admin站点,当然你也可以在你的代码中使用。

User模型的对象有两个多对多的字段:groups和user_permissions,可以像下面这样访问他们:

myuser.groups.set([group_list])
myuser.groups.add(group, group, ...)
myuser.groups.remove(group, group, ...)
myuser.groups.clear()
myuser.user_permissions.set([permission_list])
myuser.user_permissions.add(permission, permission, ...)
myuser.user_permissions.remove(permission, permission, ...)
myuser.user_permissions.clear()

1. 默认权限

默认情况下,使用manage.py migrate命令时,Django会给每个已经存在的model添加默认的权限。 假设你现在有个app叫做foo,有个model叫做bar,使用下面的方式可以测试默认权限:

add: user.has_perm('foo.add_bar')
change: user.has_perm('foo.change_bar')
delete: user.has_perm('foo.delete_bar')

2. 用户组

Django提供了一个django.contrib.auth.models.Group模型,该model可用于给用户分组,实现批量管理。用户和组属于多对多的关系。用户自动具有所属组的所有权限。

3. 在代码中创建权限

例如,为myapp中的BlogPost模型添加一个can_publish权限。

from myapp.models import BlogPost
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType

content_type = ContentType.objects.get_for_model(BlogPost)
permission = Permission.objects.create(
    codename='can_publish',
    name='Can Publish Posts',
    content_type=content_type,
)

然后,你可以通过User模型的user_permissions属性或者Group模型的permissions属性为用户添加该权限。

4. 权限缓存

权限检查后,会被缓存在用户对象中。参考下面的例子:

from django.contrib.auth.models import Permission, User
from django.shortcuts import get_object_or_404

def user_gains_perms(request, user_id):
    user = get_object_or_404(User, pk=user_id)
    # any permission check will cache the current set of permissions
    user.has_perm('myapp.change_bar')

    permission = Permission.objects.get(codename='change_bar')
    user.user_permissions.add(permission)

    # Checking the cached permission set
    user.has_perm('myapp.change_bar')  # False

    # Request new instance of User
    # Be aware that user.refresh_from_db() won't clear the cache.
    user = get_object_or_404(User, pk=user_id)

    # Permission cache is repopulated from the database
    user.has_perm('myapp.change_bar')  # True

    ...

三、在视图中认证用户

Django使用session和中间件关联请求对象和认证系统。

每一次请求中都包含一个request.user属性,表示当前用户。如果该用户未登录,该属性的值是一个AnonymousUser实例(匿名用户),如果已经登录,该属性就是一个User模型的实例。

可以使用is_authenticated方法判断用户是否登录,如果登录则返回True,如果未登录则返回False,如下视图:

if request.user.is_authenticated:
    # Do something for authenticated users.
    ...
else:
    # Do something for anonymous users.
    ...

该方法也可在模板中判定用户是否已登录。

1、登录用户

在视图中,使用认证系统的login()方法登录用户。它接收一个HttpRequest参数和一个User对象参数。该方法会把用户的ID保存在Django的session中。下面是一个认证和登陆的例子:

访问结果如下:

2、注销用户

在视图中,使用认证系统的logout()方法注销登录的用户。它接收一个HttpRequest参数,例子如下:

访问结果如下:

注意,如果用户没登录,调用logout方法不会抛出错误,如果用户已登录, 调用logout后,会清空用户的session数据。

3、用户登录的访问限制

很多时候,我们要区分已登录用户和未登录用户,只对登录的用户开放一些页面或功能,限制未登录用户的行为。办法有很多,下面是主要几种:

3.1、原始的办法

如果用户未登录,重定向到登录页面,如下所示:

from django.conf import settings
from django.shortcuts import redirect

def my_view(request):
    if not request.user.is_authenticated:
        return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
    # ...

或者显示一个错误信息:

from django.shortcuts import render

def my_view(request):
    if not request.user.is_authenticated:
        return render(request, 'myapp/login_error.html')
    # ...

3.2、函数视图使用login_required装饰器

方法参数说明

login_required(redirect_field_name='next', login_url=None)

被该装饰器装饰的视图,强制要求用户必须登录后才可以访问。

from django.contrib.auth.decorators import login_required

@login_required
def my_view(request):
    ...

该装饰器工作机制:

  • 如果用户未登陆,重定向到settings.LOGIN_URL,传递当前绝对路径作为url字符串的参数,例如:/accounts/login/?next=/polls/3/
  • 如果用户已经登录,执行正常的视图

此时,默认的url中使用的参数是“next”,如果你想使用自定义的参数,请修改login_required()redirect_field_name参数,如下所示:

from django.contrib.auth.decorators import login_required

@login_required(redirect_field_name='my_redirect_field')
def my_view(request):
    ...

如果你这么做了,你还需要重新定制登录模板,因为它引用了redirect_field_name变量。

login_required()装饰器还有一个可选的longin_url参数。例如:

from django.contrib.auth.decorators import login_required

@login_required(login_url='/accounts/login/')
def my_view(request):
    ...

注意:如果不指定login_url参数,请确保settings.LOGIN_URL已配置正确的uri,例如:

访问被装饰视图,被重定向至LOGIN_URL路径。

3.3、类视图继承LoginRequiredMixin

通过继承LoginRequiredMixin类的方式限制用户。需要注意,在多继承时,该类必须为第1个父类。

from django.contrib.auth.mixins import LoginRequiredMixin

class MyView(LoginRequiredMixin, View):
    ...

4、用户权限的访问限制

Django内置了一个permission_required()装饰器,用于根据用户权限,决定视图的访问权限,如下所示:

from django.contrib.auth.decorators import permission_required

@permission_required('polls.can_vote')
def my_view(request):
    ...

权限的格式是<app label>.<permission codename>

该装饰器还有一个可选的longin_url参数:

from django.contrib.auth.decorators import permission_required

@permission_required('polls.can_vote', login_url='/loginpage/')
def my_view(request):
    ...

5、认证视图

Django为我们提供了一系列认证相关的视图,可以直接拿来用,这样你就不需要自己写登录、注销、注册等视图。但是,但是,Django没有为认证视图提供默认的模板,你需要自己写......。

所以,除非懒癌发作,还是老老实实自己写认证相关的视图、路由和模板吧。个人认为类似跟实际生产环境结合非常紧密的视图,根本不需要这种鸡肋的内置视图,到最后,你发现还是要自己写才能满足需求。

所以,后面的部分就不赘述了!


源码等资料获取方法

 各位想获取源码的朋友请点赞 + 评论 + 收藏,三连!

三连之后我会在评论区挨个私信发给你们~

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/739511.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【前端】网页开发精讲与实战 CSS Day 1

&#x1f680;Write In Front&#x1f680; &#x1f4dd;个人主页&#xff1a;令夏二十三 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd; &#x1f4e3;系列专栏&#xff1a;前端 &#x1f4ac;总结&#xff1a;希望你看完之后&#xff0c;能对你有…

Go 并发模型—Goroutine

前言 Goroutines 是 Go[1] 语言主要的并发原语。它看起来非常像线程&#xff0c;但是相比于线程它的创建和管理成本很低。Go 在运行时将 goroutine 有效地调度到真实的线程上&#xff0c;以避免浪费资源&#xff0c;因此您可以轻松地创建大量的 goroutine&#xff08;例如每个请…

快速排序—C语言实现

目录 前言 快速排序 实现逻辑 1. hoare版本​编辑 2. 挖坑法 3. 前后指针版本 快速排序优化 1. 三数取中法选key 2. 递归到小的子区间时&#xff0c;可以考虑使用插入排序 快速排序非递归&#xff08;用栈实现&#xff09; 快速排序的特性总结 全部代码 前言 &#…

idea-spring boot开发

安装maven与配置配置maven安装插件 已经装好了idea与jdk 安装maven与配置 下载地址: https://maven.apache.org/download.cgi 下载合适的版本 配置maven 打开设置: 直接搜索 :maven 配置变量: 此电脑->属性->高级系统设置->环境变量 新建系统变量 MAVEN_HOME&#xff…

Web安全——渗透测试基础知识下

渗透测试基础 Web安全一、VMware虚拟机学习使用1、虚拟机简单介绍2、网络模式2.1 桥接网络&#xff08;Bridged Networking&#xff09;2.2 NAT模式2.3 Host-Only模式 3、通俗理解 二、Kali的2021安装与配置1、简单介绍2、Kali的版本3、配置3.1 安装虚拟机open-vm-tools-deskto…

基于matlab从ROI和蒙版在图像中创建标记(附源码)

一、前言 此示例演示如何从一组 ROI 创建标记的阻止映像。 在此示例中&#xff0c;您使用两种方法来获取和显示标记的数据。一种方法使用多边形ROI对象来存储肿瘤和正常组织区域边界的坐标。该函数将ROI坐标转换为标记的块图像。第二种方法使用掩码来指示图像的二进制分割为组…

能不能推荐个 vue 后台管理系统模板?

前言 下面是我整理的vue2和vue3的一些后台管理系统模板&#xff0c;希望对你有帮助~ Vue2 1、iview-admin Star: 16.4k 基于 iview组件库开发的一款后台管理系统框架&#xff0c;提供了一系列的强大组件和基础模板&#xff0c;方便开发人员快速搭建一套功能丰富、界面美观、…

web入门案例-部门篇

开发流程 完成对应部门管理和员工管理的需求 准备工作 注意&#xff1a;service还要写接口实体类&#xff0c;mapper只写接口即可&#xff0c;controller是实体类 对应的三个注解 RestController&#xff08;方法返回值作为响应值&#xff09; Mapper(控制反转IOC&#xff0c…

漏洞深度分析 | CVE-2023-36053-Django 表达式拒绝服务

​ 项目介绍 Django 是一个高级 Python Web 框架&#xff0c;鼓励快速开发和简洁、务实的设计。它由经验丰富的开发人员构建&#xff0c;解决了 Web 开发的大部分麻烦&#xff0c;因此您可以专注于编写应用程序&#xff0c;而无需重新发明轮子。它是免费且开源的。 项目地址…

CodeTop整理-树篇

目录 103. 二叉树的锯齿形层次遍历 236. 二叉树的最近公共祖先 124. 二叉树中的最大路径和 102. 二叉树的层序遍历 94. 二叉树的中序遍历 110. 平衡二叉树 572. 另一个树的子树 96. 不同的二叉搜索树 543. 二叉树的直径 297. 二叉树的序列化与反序列化 199. 二叉树的…

eNSP-VRRP虚拟路由器冗余技术

VRRP-虚拟路由器冗余技术 文章目录 VRRP-虚拟路由器冗余技术一、拓扑结构二、基本配置三、测试验证四、知识点详解1.VRRP路由器2.报文格式3.工作过程 一、拓扑结构 二、基本配置 R1: #配置ip <Huawei>sys [Huawei]sys r1 [r1]int g0/0/0 [r1-GigabitEthernet0/0/0]ip a…

快速排序算法!

快速排序 什么是快速排序&#xff08;quickSort&#xff09;&#xff1f; 主要分成两部分实现&#xff0c;分区、递归操作。 分区 从数组中任意选择一个 “基准”&#xff0c;所有比基准小的元素放在基准前面&#xff0c;比基准大的元素放在基本后面。 递归 递归地对基准…

Todo-List案例版本四

全局事件总线 使用步骤 1.定义全局事件总线 new Vue({...beforeCreated(){Vue.prototype.$busthis //安装全局事件总线&#xff0c;$bus就是当前应用的vm}... }) 2.使用事件总线 a.接收数据&#xff1a;A组件想接收数据&#xff0c;则在A组件中给$bus绑定自定义事件&…

Outlook---撤回(或替换)已发出的邮件

0 Preface/Foreword 发送邮件时&#xff0c;发现邮件发错了&#xff0c;或者忘了添加附件&#xff0c;那么就需要用到撤回或者替换功能。 1 撤回/替换邮件方法 步骤如下&#xff1a; 第一步&#xff1a;双击打开邮件&#xff1b; 第二步&#xff1a;找到撤回按键

自锁电路分析与应用

原理图分享 今天工作中遇到一个设计很妙的电路&#xff0c;请教了一下硬件的工程师。 大家自己直接看图可以分享出这个电路的作用吗&#xff0c;可以在评论区告诉我哦&#xff01; 自锁电路 如上图就是一个自锁电路&#xff0c;和下面的电路一样&#xff1a; 电路现象描述&a…

23.RTC实时时钟

1.STM32 RTC介绍&#xff1a; &#xff08;1&#xff09;RTC简介&#xff1a; STM32的实时时钟(RTC)是一个独立的定时器。STM32的RTC模块拥有一组连续计数的计数器&#xff0c;在相应软件配置下&#xff0c;可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和…

虚幻5-could not find root physics body 布料系统问题解决方法

不做不知道自己身体好&#xff0c;又碰到问题了&#xff1a; could not find root physics body 1.据说是Skeleton 和SkeletaMesh傻傻分不清楚 &#xff08;但就是排查后&#xff0c;就不是这个问题&#xff09; 2.重新创造一个Physic Asset吧 Creating a New Physics Asse…

【C语言初阶(13)】三子棋游戏(优化:多子棋实现)

文章目录 一、游戏的实现思路二、游戏的实现步骤1. 菜单函数2. 设置棋盘3. 初始化棋盘4. 打印棋盘5. 玩家下棋6. 电脑下棋7. 多子棋判断输赢8. 判断棋盘是否已满 三、模块化代码实现1. test.c2. game.h3. game.c 四、结果演示 由于模块化编程的需要&#xff0c;我们需要把整个游…

解决Bridge材质导入到Blender为白色的问题

文章目录 前言一、复现问题二、解决方案总结 前言 一、复现问题 在Bridge上看到一块不错的草皮, 导入成功后是白色材质: 二、解决方案 以前用这个方法导入过模型, 那时候还没启用汉化, 也没什么材质问题. 这次操作之前刚启用了汉化, 我猜是汉化导致: 取消勾选’新建数据’, 重…

【Java】-初识java

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ 如 果 你 喜 欢 作 者 的 文 章 &#xff0c;就 给 作 者 点 点 关 注 吧&#xff01; 文章目录 前言…